[net.unix-wizards] More on SUID and exec

ka (02/11/83)

Create an executable-by-everybody directory under "testdir" called
"subdir", make "subdir" executable by anybody, and perform the exec
with the current directory set to subdir.  The exec fails in the
example given because the process doesn't have execute permission on
the current directory.
				Kenneth Almquist

crp (02/13/83)

You can accomplish what you want to using an SUID process,
but you have to have an additional level of directory.
"Carrying" the user into the forbidden directory isn't enough
since the suid program abandons him to his own permissions before the exec.
The error you are getting from exec is telling you that permission
is denied for searching the current directory.
Try the following:
 drwx------          games  buffer
      drwx--x--x     games  buffer/gamesdir
         -rwx--x--x  games  buffer/gamesdir/forbidden_fruit



The suid program owned by games carries the user in past the buffer directory
(by chdir("/whatever/buffer/gamesdir"))
to a place which the unassisted user can search.
In particular, the user can execute programs in the current directory or
below in the hierarchy.  Note, however, that a pathname with ../
will not work, because the user can't walk upward out of gamesdir
(pwd, for example, won't work).

jfw (02/14/83)

GRRRRRRRR!

	Let there exist:

		drwx------  games	topdir
			drwx--x--x  games	middledir
				--x--x--x  games	. Rogue

I start Rogue, play a while, type ! to get a shell escape, and then
type "ln .\ Rogue /usr/jfw/bin/HaHaHa".  And then get to play Rogue on
the uucp dialup, over the CHAOSNET from a Lisp Machine, and during Prime
Time, all at once.  Maybe scrambling the name enough will make it take a while
to get the name right, but it can be done.

Why does FIONCLEX mode exist for files?  Is not a non-SUID exec a clean
and SUFFICIENT analogous way to achieve this purpose??

I know, games are not the most crucial application one can think of, but
aren't there any applications where you could fail to want people to run
a program without specific permission, yet you can't modify that program
to do its own checking (perhaps a binary only (GAK) license or something?).
As a UNIX minimalist, I would not even think of a kernel change if there
were any way of kludging a way of accomplishing this, having taken that
view in many other arguments around CCC...

		John Woods, ...!decvax!genradbo!mitccc!jfw

trt (02/14/83)

References: mitccc.309

FIOCLEX provides a simple way to ensure that sensitive files are not
passed along to unscrupulous programs.
For example, consider an SUID game program that opens a "secret" file
and permits the player to "!sh".  It may carefully revert uid/gid
but if it does not close the restricted file, well,
it is not a restricted file, is it?
Steve Bellovin noticed this danger some years back
and recommended liberal use of FIOCLEX as the cure.

A+ news has a local version of fopen(III), something like:
	FILE *
	xfopen(file, mode)
	char *file, *mode;
	{
		FILE *fp;

		if ((fp = fopen(file, mode)) == NULL) {
			it didnt work
		}
		ioctl(fileno(fp), FIOCLEX, NULL);
		return(fp);
	}
Alternatively, one can keep a list of file descriptors which
must be closed prior to an exec(II).  I prefer the ioctl.

FIONCLEX undoes FIOCLEX, and is probably just for completeness.
It can be simulated with dup(II) and close(II).
I could find no use of FIONCLEX in all of /usr/src/cmd.
	Tom Truscott
P.S.  Perhaps FIOCLEX should be the default when a file is opened.
A few programs such as init/getty/login/sh would then need to use FIONCLEX.

mjb (02/14/83)

The problem you mention re. shell escapes is one with rogue, if it exists.
After forking to exec a shell for a !, all programs should do:

	setuid(getuid());
	setgid(getgid());

to prevent exactly what you described. (Note: I am speaking for 4.1BSD, where
the '!' convention should be eliminated anyway and everyone forced to use
csh and ^Z instead, but that'll never happen.)

Mike Braca,  ..!decvax!brunix!mjb, mjb.brown@udel-relay

chris.umcp-cs@UDel-Relay (03/22/83)

From:  Chris Torek <chris.umcp-cs@UDel-Relay>

What we do is not entirely satisfactory, but we haven't had any
trouble.  We have cron automatically take away execute permission
for the appropriate games in the morning, and add it back in the
afternoon.  The only problem occurs when the Vax is down at the
changeover time.  That could be fixed by adding some more stuff
into /etc/rc.  It'd be something like:

	: en/dis able games if it is/isnt working hours
	if [ /usr/local/ifdate -s Wk1000-1630 ] ; then
		chmod a-x /usr/games/foo
	else
		chmod a+x /usr/games/foo
	fi

The program is -rwx--x--x 1 daemon /usr/games/foo, so no one can
copy it; if they link to it we don't care, since their link is only
executable when the original is.

('ifdate' was yanked out of UUCP's date check routines.)