[comp.unix.wizards] Pseudo-tty ownership problem

gwyn@brl-smoke.UUCP (10/03/87)

In article <730@quacky.UUCP> dce@mips.UUCP (David Elliott) writes:
>1. Change the commands that work with ptys to be setuid root.
	Extremely insecure!  Large set-UID programs nearly always
	have security holes.
>2. Change the commands to call a setuid root command that will
>   change the ownership of the given tty.
	This is workable (see the DMD "relogin" utility), but
	it doesn't solve the entire problem, which also includes
	locating a pty (or group of ptys), chown'ing and chmod'ing
	the pty, and putting it back the way it was when done.
>3. Change mesg and biff to be setuid root and add code to them
>   to figure out if the operation should be allowed ...
	NO NO NO!  It is essential that "mesg", "talk", "write", etc.
	NOT write on ptys that have not authorized such "break-
	through" writes.  Quite often I'm conducting a specialized 
	protocol between host software and downloaded interface code
	and cannot tolerate unexpected garbage being sent down that
	channel.  /etc/utmp, if it is to have any use at all, is
	the proper place to find out the terminal to be used for
	such communications.
>4. Change the pty driver in the kernel such that it sets the owner
>   of a pty slave to the userid of the owner the first time the
>   pty is opened for writing.
	Yuck!  It doesn't solve the entire problem.
>Any help or additional ideas are welcome.
	A pty manager daemon, which hands out ptys upon request
	(setting their owner and modes) would be useful.  It can
	also update /etc/utmp upon request.  The latter function
	could be delegated to a "relogin" utility, which is useful
	in its own right (e.g. when a user wants to change which of
	his layers is to be the "communication layer").
	The hard part is making sure the pty is properly reset
	(owner, mode) when the application is through with it.

ron@topaz.rutgers.edu (Ron Natalie) (10/04/87)

Enclosed... A program that when made setuid root allows a user who
is so authorized to chown a pty to himself and free it up later.
I needed this for when I added user mode attach/detach to UNIX.
This program must be called with the open control side of the PTY
as file descriptor 0 (to prove that the user has passed the kernel
restrictions on who can use the pty) and the name of the PTY.
There was code to create a UTMP entry for the pty (-u) and delete
the utmp entry when done, but I've removed that as it was shamelessly
stolen from some other program which is probably under license
(I think it was login).
--- Cut Here ---
#include <sys/types.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/file.h>

char	*filename = "/dev/ptyxx";

main(argc, argv)
	int	argc;
	char	**argv;
{
	int	i;
	int	foo = 0;
	int	aflag = 0;
	int	dflag = 0;
	int	uflag = 0;
	char	*ptyname = 0;


	struct	stat	statf, statd;

	while(--argc)  {
		++argv;
		if(*argv[0] == '-')  {
			if(argv[0][1] == 'a')
				aflag++;
			if(argv[0][1] == 'd')
				dflag++;
			if(argv[0][1] == 'u')
				uflag++;
		} else
			ptyname = *argv;
	}

	if( (aflag + dflag) != 1  || (ptyname == 0))  {
		fprintf(stderr, "Usage:  pty {-a or -d} ptycontrol\n");
		exit(1);
	}
	filename[8] = ptyname[0];
	filename[9] = ptyname[1];
	
	if(stat(filename, &statd) == -1)  {
		perror(filename);
		exit(2);
	}
	if(fstat(0, &statf) == -1)  {
		perror("std in");
		exit(3);
	}
	if(( statd.st_mode&S_IFMT) != S_IFCHR)  {
		fprintf(stderr, "%s: not a pty\n", filename);
		exit(4);
	}
	if(( statf.st_mode&S_IFMT) != S_IFCHR)  {
		fprintf(stderr, "std in: not a pty\n");
		exit(5);
	}
	if(statf.st_rdev != statd.st_rdev)  {
		fprintf(stderr, "std in does not match pty controller\n");
		exit(6);
	}
	filename[5] = 't';
	
	if(aflag)  {
		chmod(filename, 0611);
		i = chown(filename, getuid(), getgid());
	}
	if(dflag)  {
		rmut();
	}
	if(i == -1)  {
		perror(filename);
		exit(7);
	}
	exit(0);
}

brad@bradley.UUCP (10/07/87)

Also with the window program under 4.3 if someone writes to you
with talk, you can't. What you have to do is quit window then use
talk (or suspend window, which suspends your window process, like
your kermit, compile,....).

brad