grab_vcsa.pp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. program grab_vcsa;
  2. {$I-}
  3. {
  4. This file is part of the Free Pascal run time library.
  5. Copyright (c) 2005 by Daniël Mantione
  6. member of the Free Pascal development team.
  7. VCSA grabber program for Linux.
  8. See the file COPYING.FPC, included in this distribution,
  9. for details about the copyright.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. }
  14. uses baseunix,termio;
  15. {This program helps the video unit to use /dev/vcsa* to provide high
  16. quality output.
  17. Normally, when you login, the owner of the tty you are running on,
  18. /dev/tty0-31 is set to your username. Weird enough, this is not done
  19. with the video buffer devices belonging to that tty, /dev/vcs0-31
  20. and /dev/vcsa0-31. This makes it impossible to do high quality text
  21. mode video output.
  22. This program, designed to be run suid root, reads the owner and mode
  23. of the tty, and assigns them to the corresponding vcs and vcsa device.}
  24. {Security design:
  25. - It has been checked if the user can provide any input to the program.
  26. The only input in the program is stdinputhandle, which cannot be
  27. controlled by the user. The user has therefore no control in any way
  28. about the code flow in the program; the code that is going to be
  29. executed is fixed no matter what a user does.
  30. - Outputs are the file permissions of /dev/vcs* and /dev/vcsa*. It has
  31. been considered if users could use the program this way to gain rights
  32. they should not have. By having access to /dev/vcs* and /dev/vcsa*
  33. the user can garble his own screen. This should not be a problem.
  34. After the user has logged out /dev/vcs* and /dev/vcsa* are automatically
  35. changed back to root. This removes the need for us to change permissions
  36. back again. If we would change permissions back, it would be useless, the
  37. user can kill the process before it changes back permissions.
  38. - Normal users cannot write to /dev/ and can therefore not use the program
  39. do change the permissions of other files than the actual devices.
  40. }
  41. const result_success=0;
  42. result_not_on_console=1;
  43. result_stat_error=2;
  44. result_chown_error=3;
  45. result_chmod_error=4;
  46. result_not_owner_error=5;
  47. var thistty:string;
  48. tty,vcs,vcsa:string;
  49. ttystat:stat;
  50. s:string[15];
  51. c:char;
  52. ppid,pid,parent,dummy:integer;
  53. device:longint;
  54. f:text;
  55. found_vcsa:boolean;
  56. begin
  57. exitcode:=result_not_on_console;
  58. thistty:=ttyname(stdinputhandle);
  59. if isatty(stdinputhandle)=1 then
  60. begin
  61. pid:=fpgetpid;
  62. repeat
  63. str(pid,s);
  64. assign(f,'/proc/'+s+'/stat');
  65. reset(f);
  66. if ioresult<>0 then
  67. begin
  68. found_vcsa:=false;
  69. break;
  70. end;
  71. read(f,dummy);
  72. read(f,c);
  73. repeat
  74. read(f,c);
  75. until c=' ';
  76. repeat
  77. read(f,c);
  78. until c=' ';
  79. ppid:=pid;
  80. read(f,pid);
  81. read(f,dummy);
  82. read(f,dummy);
  83. read(f,device);
  84. close(f);
  85. found_vcsa:=device and $ffffffc0=$00000400; {/dev/tty*}
  86. if (device=0) or (pid=-1) or (ppid=pid) then
  87. break; {Not attached to a terminal, i.e. an xterm.}
  88. until found_vcsa;
  89. if found_vcsa then
  90. begin
  91. {We are running on the Linux console}
  92. str(device and $0000003f,s);
  93. tty:='/dev/tty'+s;
  94. if fpstat(tty,ttystat)<>0 then
  95. halt(result_stat_error);
  96. if ttystat.st_uid<>fpgetuid then
  97. halt(result_not_owner_error);
  98. vcs:='/dev/vcs'+s;
  99. vcsa:='/dev/vcsa'+s;
  100. {Change owner and group to that of /dev/tty??.}
  101. if fpchown(vcs,ttystat.st_uid,ttystat.st_gid)<>0 then
  102. halt(result_chown_error);
  103. if fpchown(vcsa,ttystat.st_uid,ttystat.st_gid)<>0 then
  104. halt(result_chown_error);
  105. {Change permissions to that of /dev/tty??.}
  106. if fpchmod(vcs,ttystat.st_mode)<>0 then
  107. halt(result_chmod_error);
  108. if fpchmod(vcsa,ttystat.st_mode)<>0 then
  109. halt(result_chmod_error);
  110. exitcode:=result_success;
  111. end;
  112. end;
  113. end.