understanding Linux capabilities brokenness

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

 



Hi.

Like many people[#1][#2], I have found out that the Linux capability
handling utilities are non-functional, and cannot be repaired because
the kernel deliberately cripples capabilities (they are reset on every
call to execve()).  I have found that various people[#1][#2] have
proposed patches to restore working capabilities.  However, the matter
seems rather complicted and I would like to understand the full story.
Hours of Google-grepping through the lkml archives has not helped me
very much, so I hope someone can get the history straight.

I understand that Linux capabilities first appared seven or eight
years ago, and in 2000-06 there was a serious fault discovered which
caused a local root exploit through the use of the sendmail problem.
Rading [#3] and [#4], I understand that the problem was this:

  When sendmail is invoked by a non-root user, it attempts to drop its
  root privileges (which it has because the binary is installed suid)
  by calling setuid(getuid()), which, due to the stupidity of
  traditional Unix semantics enshrined in the POSIX/SUS standards,
  operates differently according to whether the process has
  "appropriate privileges" (in which case it sets all its UIDs to its
  real UID) or not (in which case it preserves the saved UID); now
  under Linux, "appropriate privileges" is defined[#5] as possessing
  the CAP_SETUID capability.  So if a non-root user manages to execute
  sendmail without the CAP_SETUID capability, the setuid(getuid())
  call will fail (or rather, not perform as expected), and the genie
  is out of the bottle.

However, what I do not understand is precisely _how_ one gets a
sendmail process without CAP_SETUID: for that is the heart of the
problem, and that is where the bug really was.  But [#3] and [#4] are
very obscure (and I found nothing conclusive in lkml archives).  I
understand that the problem lies in some combination of the
inheritable capability set and the CAP_SETPCAP capability, but I don't
see what that combination is.  Certainly removing capabilities from
the inheritable set should not prevent suid root programs from having
them reinstated (in the language of [#6], the suid root bit should
correspond to a full forced set of capabilities), so I don't see what
that has to do with it, and CAP_SETPCAP indeed allows to remove
capabilities from a given process but I don't see how the user could
gain that capability (and indeed if he can then we can expect him to
gain all capabilities very rapidly).

Can someone describe very accurately what the problem was?  And why
was it "fixed"[#7] by completely disabling capability inheritance and
also by disabling the CAP_SETPCAP capability?  In other words, suppose
I restore CAP_SETPCAP on my system and/or make capabilities fully
inheritable on execve() (that is, just take the logical AND of the
permitted set with the inheritable set, except if the executed program
is suid root, in which case all three sets - permitted, effective and
inheritable - are set to full): what is the security problem in this?

Assuming I want to make capabilities inheritable, is there a
recommended patch for doing so?  Alexander Nyberg's patch in [#1]
looks good to me (at least, it seems to do exactly what I want), but
how well has it been tested?  Is this something that might eventually
make its way into the official kernel, or is this a no-goer?  Also, if
the author happens to read this, I'd like an explanation on the "Is
this a root task that did seteuid before execve? if so it wanted its
effective permissions dropped" comment in cap_bprm_apply_creds().

Thanks!

-- 
     David A. Madore
    ([email protected],
     http://www.madore.org/~david/ )

[#1] <URL: http://groups-beta.google.com/group/fa.linux.kernel/browse_thread/thread/f76dcb9447a77c34 >

[#2] <URL: http://groups-beta.google.com/group/fa.linux.kernel/browse_thread/thread/4366e557a75a933d >

[#3] <URL: http://www.cs.berkeley.edu/~daw/papers/setuid-usenix02.pdf >

[#4] <URL: http://www.sendmail.org/sendmail.8.10.1.LINUX-SECURITY.txt >

[#5] I tend to think that the behavior of setuid() is wrong in the
first place, that is, setuid(getuid()) should also change the saved
UID as soon as the effective UID is zero, even if CAP_SETUID is not
set, to make sure that traditional Unix semantics are observed.  (More
recent, capability-aware, programs will use setresuid() anyway.)  But
that is rather beside the point.

[#6] <URL: http://ftp.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.4/capfaq-0.2.txt >

[#7] I wanted to find exactly on which kernel version the changes took
place.  Unfortunately, <URL: http://lxr.linux.no/ > only has major
versions, the 2.2.15->2.2.16 patch is very hard to read, and I have
neither the patience nor the bandwidth to unpack entire kernel trees
on my PC to unravel the full history...
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]
  Powered by Linux