Re: BEWARE! Linux seteuid is broken!

Stephen R. van den Berg (srb@cuci.nl)
Tue, 18 Jun 1996 13:25:41 +0200


"Theodore Y. Ts'o" <tytso@mit.edu> wrote:
>OK, I've done some research into this problem, and the real problem is
>that BSD has changed how they handled seteuid(). (This is not the first

That's what I've been trying to explain.

>FreeBSD emulates setreuid() using a different algorithm, which
>interestingly enough looks like they stole the algorithm from Linux. At

>the very least, the algorithm for when to set the saved user id argument
>is *exactly* the same as the Linux algorithm. Very suspicious....

That might partly be my fault. About 1.5 years ago, I noticed some
very annoying features with respect to setreuid() which prevented some
of my applications from working under Linux. I then compared and
merged the setre[gu]id() semantics of FreeBSD and Linux with respect
to saved [ug]id handling (at least, up to a point, I stopped as soon
as my own applications worked satisfactory).

>The real difference is that FreeBSD treats seteuid() the way BSD 4.4
>does, instead of the way BSD 4.3 does. Since Linux is BSD 4.3
>compatible, seteuid() is treated like setreuid(-1, euid) --- and this
>would be correct for BSD 4.3.

>So, the answer is not to change setreuid() --- setreuid() is correct as
>it currently stands in Linux. Rather, now that we know that BSD 4.4 has
>gratuitously changed how seteuid() works, it's certainly reasonable for
>us to put support into the kernel for BSD 4.4 seteuid(). In fact,
>here's the bit code to do it (see below). Of course, it doesn't include

>+asmlinkage int sys_seteuid(uid_t euid)
>+{
>+ if ((euid == current->uid) || (euid == current->suid) || suser())

You forgot to check for current->euid == euid.

>+ current->fsuid = current->euid = euid;
>+ else
>+ return -EPERM;

However, I think you're wrong in creating yet another system call and
not fixing setreuid(). I never understood why you bother changing the
saved uid and saved gid whenever setreuid() is called?

The idea is that, as soon as a process *execs*, the euid and egid
are copied to svuid and svgid. There *are* no security holes that
need to be plugged for traditional BSD 4.3 programs. As soon as they
exec, the holes are plugged. If they do *not* exec, then they might
have some extra opportunities to switch back to the old [ug]ids. But,
since that is in the same binary, the program must already cope with
that anyway.

I'd say, drop the whole saved [ug]id changes whenever setre[ug]id() are
called and the world will be a better place.

-- 
Sincerely,                                                          srb@cuci.nl
           Stephen R. van den Berg (AKA BuGless).
Auto repair rates: basic labor $40/hour; if you wait, $60; if you watch, $80;
if you ask questions, $100; if you help, $120; if you laugh, $140.