[net.bugs.v7] unexpected alarms

henry@utzoo.UUCP (Henry Spencer) (01/03/85)

There is a destructive security bug in almost every existing Unix version.
Try writing a program that sets an alarm and then execs, say, passwd(1).
A few seconds later, passwd(1) gets the alarm and drops dead, perhaps in
the middle of an update to /etc/passwd.

This problem definitely exists in V7.  Inspection of source indicates
that it probably exists in System V.  (We have, but do not run, SysV.)
I haven't summoned up the courage to check 4.2.

Clearly, the *wrong* thing to do is to require every setuid program
to reset the alarm.  People writing setuid programs have enough to worry
about already.  There is also an important corollary of the Law of Least
Astonishment:  if you don't use a facility, you shouldn't have to care
about it.

One can argue that alarms should not be allowed to persist across exec(2)
at all.  This is probably stronger than necessary, however, and there are
a few uses for such persistence; see page 229 of Kernighan&Pike for an
example.  However, not allowing alarms to persist across an exec of a
setuid (or setgid) program seems appropriate.

In V7 (SysV is similar, dunno about Berklix), late in sys1.c/getxfile(),
you will find the code that implements setuid.  It's trivial to add the
statement:

	u.u_procp->p_clktim = 0;

to the uid-setting and gid-setting if's.
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry

geoff@desint.UUCP (Geoff Kuenning) (01/08/85)

In article <4861@utzoo.UUCP> henry@utzoo.UUCP (Henry Spencer) writes:

>One can argue that alarms should not be allowed to persist across exec(2)
>at all.  This is probably stronger than necessary, however, and there are
>a few uses for such persistence; see page 229 of Kernighan&Pike for an
>example.  However, not allowing alarms to persist across an exec of a
>setuid (or setgid) program seems appropriate.

Gee, the way I read the code (the description starts on 229, the code is on
page 230), the alarm is indeed left on in the child, but this is a bug, not
the way teh program was supposed to work.  There should be an alarm(0) call
just before the execvp call;  the child will be killed with SIGKILL by the
onalarm() routine.

It seems to me that this type of code can handle any case where you want the
effect of "leaving around" an alarm.  After all, if you do SIGALRM instead of
SIGKILL, the child process can't even tell the difference -- except that you
can't do it if the kid is suid.

I vote for setting u.u_procp->p_clktim to zero on all exec's, not just suid
ones.  I think this comes closer to the principle of "least astonishment"
anyway.
-- 

	Geoff Kuenning
	...!ihnp4!trwrb!desint!geoff

henry@utzoo.UUCP (Henry Spencer) (01/08/85)

Blush.  Several people have pointed out that the stuff on page 229 of
Kernighan&Pike does *not* rely on alarms persisting across exec.  My
mistake; I was originally looking around for any sign that the behavior
might be useful, and I looked at the K&P discussion but not at the
code.

Does anybody know of any case where the persistence of alarms across
exec is genuinely useful?  I personally think that just cancelling
them altogether is the right thing to do.  My kernel mod cancels them
only for setuid/gid programs simply because this was the minimum change
in behavior needed to make things safe.
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry

anton@ucbvax.ARPA (Jeff Anton) (01/10/85)

In article <4889@utzoo.UUCP> henry@utzoo.UUCP (Henry Spencer) writes:
>Does anybody know of any case where the persistence of alarms across
>exec is genuinely useful?  I personally think that just cancelling
>them altogether is the right thing to do.  My kernel mod cancels them
>only for setuid/gid programs simply because this was the minimum change
>in behavior needed to make things safe.

I have used the persistence of the alarm signal in a debatably
useful mannor.  I've a graphics program for the SUN workstation
that runs until interuption that I use in my .logout file.
In that file a command that checks if I'm on the console and if so,
sets an alarm for a minute and then execs my graphics.  I did not have
to modifiy my program to have a "time to die" option.

I'd like to keep the persistent alarm for that case.  I've written
a general process supervisor that kills programs if the load goes
to high or if it runs too long.  I think the persistant alarms
would be an easy way to limit program execution time.

Aside from the above, I think cancelling alarms across execs of
set[ug]id file would be a safer thing to do.  And, in the future,
setid programs should be written with the alarm signal in mind.
(Actually every signal should be considered where writeing these
programs.  One never knows.)
___________
C knows no bounds.
				Jeff Anton
				U.C. Berkeley
				ucbvax!anton
				anton@berkeley.ARPA