tech-security archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: enforcing RLIMIT_NPROC in setuid() ?



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


I'm not sure that I understood the whole situation with sshd.

Did sshd fork() as root, setuid() and then exec() some command that was
provided to it?  That the only way that I can see being able to get
around enforcement by fork().

If sshd would work after it invoked setuid(), that would catch the
problem. That would fail normally and everything would be as expected.
I agree that just fixing sshd is not enough in general, but have to
recognize that this can't happen without the help of a super-user
process to exceed the limit.

The whole RLIMIT_NPROC stuff is bizarre as a limit, as you can actually
(as I recall) have different process trees under the same UID, that have
different limits.  The tree that has a higher limit goes on it's way,
fork()ing for fun and profit, and the tree with the lower limit, just
runs out when the total exceeds' it's limit.  (unless this has changed
recently)

One possibility is that a process doing setuid() that exceeds the limit
simply doesn't return from the setuid().  That would be bizarre and hard
to diagnose.  A new bit in wait() or something might help, but it would
still be difficult.

Maybe if the setuid() marked the process as "infringing", and unless
upon an exec() the user was below the limit, the exec() would
fail. exec() already can fail for various reasons which various
processes including sshd need to report to the user.

One of the beauties of exec(2) is that it doesn't create a new process,
so it should never fail because we've run out of processes --- there are
likely some applications that depend upon this.  They shouldn't get into
trouble however, unless they got marked as infringing when they did
setuid.

In the end, I hate setuid.  We've need a two phase commit.
How many times have you wanted to:
         a) change your uid to a non-priveledged it.
         b) chroot to a safe place
         c) exec another process (statically linked of course) which
            might be less well written (thus (a) and (b)!)

I used to do:
  chdir("/some/place/for/the/bin");
  chroot("/some/safe/place");
  setuid(mynobody);
  exec("unsafeprog");

I'd put: chdir("/")
at the beginning of unsafeprog, which would give up the cwd that we
used to find the binary.  That "hole" was closed in chroot(2) awhile
ago.  Now you have to leave the binary in the chroot() area, or move the
chroot() call into the binary... Some OSs added fexec(2) 

It would be nice if we could have a call which was really
   setuid-upon-next-exec().

I wonder if we could just have seteuid() cause the current process to
take on the resource limits of the new user, and setuid() would make
the situation permanent?

- -- 
]           Bear: "Me, I'm just the shape of a bear."          |  firewalls  [
]  Michael Richardson,    Xelerance Corporation, Ottawa, ON    |net architect[
]mcr%xelerance.com@localhost      http://www.sandelman.ottawa.on.ca/mcr/ 
|device driver[
]panic("Just another Debian GNU/Linux using, kernel hacking, security guy"); [










-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Finger me for keys

iQEVAwUBR4aYPICLcPvd0N1lAQJZZAf8CVZMeXdYxOKVI9U/zttjE/R/3IDWiooM
ZmjVIeGBKLy/DY9WGDQT/kF+w8SXXofeXAU+JBm0E5RROibs1U4gFdVP97ClneZe
HhS+cKoHcFqTZdT8dhphP/67WvKcGaxEmj36uzJcoh11jWrNuvFouqvs/ZrUgpdQ
28/sK1x1WRbY3EuP9dHegSluHYWxETLk6YT7axJBE1FeB/QyN+Ato5jgdGOlPCSv
pSYJC4iRp/3zH4O9fS7wJOiyGhWnQWa1nhvlo9eHi/E1jJiDWwNgN/zY1y0CB7/q
qJ9P+Z7X/YBvo5V7YM/C/LLv/quLsAgusMeL6ErZ9oIAC5sJnUcwtg==
=eTlK
-----END PGP SIGNATURE-----



Home | Main Index | Thread Index | Old Index