User Tools

Site Tools


ironpenguin:capability_notes

The IronPenguin capability system is almost but not quite the POSIX capability draft. The differences are the result of both a deeper analysis of the security considerations and of practical experiances form various POSIX systems attemption to implement the POSIX draft, including the Linux kernel.

The IronPenguin capabilities do NOT remove the concept of root by default. Instead, they modify the current (2.6.x) Linux kernel approach.

The vanilla kernel has process capabilities internally, but implements 'legacy support' by automatically granting all capabilities except for CAP_SETPCAP (see setpcap for a discussion of that capability) to any process whose UID or EUID is 0 (root).

In IronPenguin, the sysctl /proc/sys/kernel/cap-root-special determines which (if any) capabilities are automatically granted to root. This mask starts out equal to cap-bound (/proc/sys/kernel/cap-bound). Bits may be cleared from this variable, but can only be set by rebooting the system.

Further, a processes capceiling limits the capabilities that may be granted to (e)uid 0.

Great care must be used in clearing capabilities from cap-root-special however. While clearing a default capability FEELS like an increase in security, there has already been a notable exploit published which lead to the vanilla kernel's current handling.

Some programs are setuid-root and to maintain security will set their own uid to a non-root user after initialization. A good example is procmail.

Procmail runs as root initially. It reads the mail to be delivered to determine the recieving user. It then calls setuid on itself to become that user in order to proccess the mail safely. After becoming the non-privileged user, it opens $HOME/.forward (if it exists) and delivers the mail accordingly. This means that the user can cause arbitrary programs to be run by procmail anytimemail is delivered. Normally this is acceptable since they will be run as that user (and so they can't do anything through their .forward that they couldn't do at the command line).

However, an exploit exists where the user first drops all capabilities from permitted, inhereted and effective, then mails himself. This, in turn invokes procmail setuid root but with no capabilities.

The key problem is that /etc/passwd and /etc/shadow are OWNED by root. This means that procmail running as root does NOT require any capabilities to manipulate these two security critical files.

Since procmail does NOT have CAP_SETUID, it's attempt to become the user fails. Since that call “cannot fail” on a legacy system, procmail apparently does not (or did not at that time) check for failure before continuing.

As a result, it would happily run a user script like:

echo "badguy:x:0:0:/root:/bin/bash">>/etc/passwd
chmod u+w /etc/shadow
echo "blah blah" >>/etc/shadow
chmod u-w /etc/shadow

as root. Since passwd and shadow are owned by root, this is permitted even though the process has no capabilities set and so will create a new root user with a password known to the attacker.

It is technically correct to argue that this is procmail's fault for not terminating when setuid fails. It is also correct to argue that procmail should have has CAP_SETUID set and no others and should have been updated to understand the new security model. It is technically correct to argue that if root is no longer special, perhaps passwd and shadow should be owned by some other system id.

However, the old way worked perfectly well before, and it is human nature th not think of everything when updating a large feature rich system.However technically correct those arguments may be, it was STILL an accident waithing to happen.

Given that the paradigm of setuid-root then become non-root to do something on the user's behalf is a common one, there are a number of these accidents waiting to happen. This is a strong argument to leave cap-root-special as-is until a very careful analysis of potential consequences is performed.

Perhaps the kernel should be modified to never honor setuid-root in an executable, at least long enough to find these cases and eliminate them. However, the better answer is to leave CAP_SETUID in cap-root-special for now, and then analye all setuid-root programs on the system carefully.

An important lesson here is that no matter how many times it is said that root isn't special in a capabilities system, root IS special so long as it owns system directories, logs, and expecially the password database. setuid-root is NOT without consequence just because no capabilities are granted, and if the app in question expects to use it's root privileges, NOT granting them can create a security problem where none existed before.

It is noteworthy that as long as legacy systems exist which are otherwise compatible with a full capability system, simply installing a package without auditing for setuid-root installed binaries can easily introduce new and exciting holes in a previously secured system. Perhaps the package tools should be setuid-nonroot with all filesystem related capabilities set except for CAP_FSETID so it CAN'T install a file setuid-root.

This is by no means meant to be the last word on the subject, and the focus on CAP_SETUID should not be interpreted to mean no other capability (or lack of capability) can result in similar “paradixical” security failures. It SHOULD be interpreted to mean the other capabilities are not yet analysed with sufficient rigor to publish any findings.

The best advice for now is that default root capabilities (particularly CAP_SETUID should NOT be cleared unless or until all setuid programs in the system have been audited thoroughly and either “demoted” to merely have one or two capabilities set OR can be shown to do the right thing with no capabilities set.

For an example, the passwd command is a cantidate for a setuid-root with no capabilities if modufied to chmod /etc/shadow rather than depend on CAP_DAC_OVERRIDE. The real question is which is preferable, granting CAP_DAC_OVERRIDE of chmoding /etc/shadow in order to update a password.

ironpenguin/capability_notes.txt · Last modified: 2010/04/15 21:18 (external edit)