how to setuid for shell scripts?

Maarten Litmaath maart at cs.vu.nl
Tue Nov 20 06:53:12 AEST 1990


In article <4432 at auspex.auspex.com>,
	guy at auspex.auspex.com (Guy Harris) writes:
)...
)On top of that, there's a hole with "#!" that's present in almost all
)systems - I think it's fixed in S5R4 and think it'll be fixed in 4.4BSD
)- that you *can't* plug except by doing fixes of the sort done in those
)systems.
)
)There are alternatives to "#!"; Maarten Litmath has a program whose name
)I've forgotten that you can use (he says, in an attempt to prompt
)Maarten to follow up :-)).

OK!  :-)
The program is called `indir', because a script starting with
`#!/path/of/indir' is interpreted INDIRectly.  (Does anyone remember V7's
indir(2) system call?)  Note: `indir' is a generalized version of the
`setuid' program; the former can handle non-setuid scripts as well, e.g.
scripts which are hindered by the limited length of a `#!' line.
Example:

	#!/usr/local/bin/indir -u
	#?/bin/sh /safe/path/to/the/setuid/script lots of options
	shell commands

Right.  Tom Christiansen already explained the race condition hole.
Now how about S5R4 and 4.4BSD?  I've been informed that both operating
systems are to launch setuid scripts through the /dev/fd driver.

For example, assume the file `/bin/foo' is a setuid root shell script,
then the kernel handles a system call

	execl("/bin/foo", "foo", "args", (char *) 0)

like this:

	fd = open("/bin/foo", 0);
	fstat(fd, &statbuf);
	if (statbuf.st_mode & S_ISUID)
		seteuid(statbuf.st_uid);
	sprintf(buf, "/dev/fd/%d", fd);
	execl("/bin/sh", "sh", "-", buf, "args", (char *) 0);

Now we're sure the right file gets executed with the right permissions.
However, there appear to be 2 problems with this approach:

1)	`ps' will show something like this -

		  PID TT STAT  TIME COMMAND
		 5393 p1 R     0:00 sh - /dev/fd/3

	- not very informative...

2)	the following construct wouldn't work for setuid sh scripts -

		case $0 in
		foo)
			# the `foo' link was executed
			foo_stuff
			;;
		bar)
			# the `bar' link was executed
			bar_stuff
			;;
		*)
			echo "Unknown service requested.  Abort." >&2
			exit 1
		esac

	- not so nice...

Am I right, Chris?
--
nreadwin at micrognosis.co.uk (Neil Readwin) on "snuff" films:
"Seen one ? I was *in* one. They tortured me horribly and then killed me
 with a single shot in the back of the head ! Following total brain death
 I gave up acting and became a VMS hacker."



More information about the Comp.unix.internals mailing list