mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-15 22:39:28 +02:00

- Disable shared linking for now since it since it simply breaks svn. (Already disabled in Makefile itself, likely accidentally done with an old FPCMake, but it "fixed" svn to compile.) git-svn-id: trunk@2401 -
133 lines
4.2 KiB
ObjectPascal
133 lines
4.2 KiB
ObjectPascal
program grab_vcsa;
|
|
|
|
{$I-}
|
|
|
|
{
|
|
This file is part of the Free Pascal run time library.
|
|
Copyright (c) 2005 by Daniël Mantione
|
|
member of the Free Pascal development team.
|
|
|
|
VCSA grabber program for Linux.
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
}
|
|
|
|
uses baseunix,termio;
|
|
|
|
{This program helps the video unit to use /dev/vcsa* to provide high
|
|
quality output.
|
|
|
|
Normally, when you login, the owner of the tty you are running on,
|
|
/dev/tty0-31 is set to your username. Weird enough, this is not done
|
|
with the video buffer devices belonging to that tty, /dev/vcs0-31
|
|
and /dev/vcsa0-31. This makes it impossible to do high quality text
|
|
mode video output.
|
|
|
|
This program, designed to be run suid root, reads the owner and mode
|
|
of the tty, and assigns them to the corresponding vcs and vcsa device.}
|
|
|
|
{Security design:
|
|
|
|
- It has been checked if the user can provide any input to the program.
|
|
The only input in the program is stdinputhandle, which cannot be
|
|
controlled by the user. The user has therefore no control in any way
|
|
about the code flow in the program; the code that is going to be
|
|
executed is fixed no matter what a user does.
|
|
|
|
- Outputs are the file permissions of /dev/vcs* and /dev/vcsa*. It has
|
|
been considered if users could use the program this way to gain rights
|
|
they should not have. By having access to /dev/vcs* and /dev/vcsa*
|
|
the user can garble his own screen. This should not be a problem.
|
|
|
|
After the user has logged out /dev/vcs* and /dev/vcsa* are automatically
|
|
changed back to root. This removes the need for us to change permissions
|
|
back again. If we would change permissions back, it would be useless, the
|
|
user can kill the process before it changes back permissions.
|
|
|
|
- Normal users cannot write to /dev/ and can therefore not use the program
|
|
do change the permissions of other files than the actual devices.
|
|
}
|
|
|
|
const result_success=0;
|
|
result_not_on_console=1;
|
|
result_stat_error=2;
|
|
result_chown_error=3;
|
|
result_chmod_error=4;
|
|
result_not_owner_error=5;
|
|
|
|
var thistty:string;
|
|
tty,vcs,vcsa:string;
|
|
ttystat:stat;
|
|
s:string[15];
|
|
c:char;
|
|
ppid,pid,parent,dummy:integer;
|
|
device:longint;
|
|
f:text;
|
|
found_vcsa:boolean;
|
|
|
|
begin
|
|
exitcode:=result_not_on_console;
|
|
thistty:=ttyname(stdinputhandle);
|
|
if isatty(stdinputhandle)=1 then
|
|
begin
|
|
pid:=fpgetpid;
|
|
repeat
|
|
str(pid,s);
|
|
assign(f,'/proc/'+s+'/stat');
|
|
reset(f);
|
|
if ioresult<>0 then
|
|
begin
|
|
found_vcsa:=false;
|
|
break;
|
|
end;
|
|
read(f,dummy);
|
|
read(f,c);
|
|
repeat
|
|
read(f,c);
|
|
until c=' ';
|
|
repeat
|
|
read(f,c);
|
|
until c=' ';
|
|
ppid:=pid;
|
|
read(f,pid);
|
|
read(f,dummy);
|
|
read(f,dummy);
|
|
read(f,device);
|
|
close(f);
|
|
found_vcsa:=device and $ffffffc0=$00000400; {/dev/tty*}
|
|
if (device=0) or (pid=-1) or (ppid=pid) then
|
|
break; {Not attached to a terminal, i.e. an xterm.}
|
|
until found_vcsa;
|
|
if found_vcsa then
|
|
begin
|
|
{We are running on the Linux console}
|
|
str(device and $0000003f,s);
|
|
tty:='/dev/tty'+s;
|
|
if fpstat(tty,ttystat)<>0 then
|
|
halt(result_stat_error);
|
|
if ttystat.uid<>fpgetuid then
|
|
halt(result_not_owner_error);
|
|
vcs:='/dev/vcs'+s;
|
|
vcsa:='/dev/vcsa'+s;
|
|
|
|
{Change owner and group to that of /dev/tty??.}
|
|
if fpchown(vcs,ttystat.uid,ttystat.gid)<>0 then
|
|
halt(result_chown_error);
|
|
if fpchown(vcsa,ttystat.uid,ttystat.gid)<>0 then
|
|
halt(result_chown_error);
|
|
|
|
{Change permissions to that of /dev/tty??.}
|
|
if fpchmod(vcs,ttystat.mode)<>0 then
|
|
halt(result_chmod_error);
|
|
if fpchmod(vcsa,ttystat.mode)<>0 then
|
|
halt(result_chmod_error);
|
|
exitcode:=result_success;
|
|
end;
|
|
end;
|
|
end.
|