How SE Linux Prevents Local Root Exploits

In a comment on my previous post about SE Linux and worms/trojans [1] a user enquired about which methods of gaining local root are prevented by SE Linux.

A local exploit is one that can not be run remotely. An attack via TCP or UDP is generally considered a remote exploit – even though in some cases you might configure a daemon to only bind to localhost (in which case the TCP or UDP attack would only work locally). When compromising a machine it’s not uncommon for a local exploit to be used after a remote exploit or social engineering has been used to gain non-root privileges.

The two most common types of local root exploit seem to be those which attack the kernel and those which attack a SETUID process. For a non-SE Linux system it usually doesn’t matter much how the local exploit is run. But a SE Linux system in a default configuration will be running the Targeted policy that has almost no restrictions on a user shell session. So an attacker who wants to escalate their privileges from local user to local root on a typical SE Linux system has a significant benefit in starting from a user account instead of starting from a web server or other system process.

In the SE Linux model access is granted to a domain, and the domain which is used for a process is determined by the policy based on the domain of the parent process and the labelling of the executable. Some domains are not permitted to transition to any other domains, such as the domain dhcpd_t (used for a DHCP server). Other domains are only permitted to transition to a small set of domains, for example the domain httpd_t (used for a web server) can only transition to a small number of domains none of which has any significant privileges.

On a machine running without SE Linux a compromise of a DHCP server is game-over as the server runs as root. A compromise of a daemon such as Apache on a machine without SE Linux gives unrestricted access to run applications on the systems – if a SETUID-root program has a security flaw then you lose. The same bug in a SETUID program on a machine running SE Linux is not fatal because SE Linux will prevent the program from doing anything that it’s parent could not do – even if an attacker made Apache run a buggy SETUID program the broken program in question could do nothing other than what Apache is normally permitted to do.

A security flaw in a SETUID-root program on a SE Linux system can still be exploited by a local user (someone who has logged in) when running the Targeted policy. When running the Strict or MLS policies many such vulnerabilities will not be exploitable by local users (for example exploiting PING would only permit network access).

As a rule of thumb you should consider that a kernel security flaw will make it possible to bypass all other security features. However there are some situations where SE Linux can prevent local exploits. One example is a bug discovered in July 2006 which allowed the creation of SETUID files under /proc [2], the targeted policy of SE Linux prevented this from working. Another example is CVE-2003-0127 [3] (a kernel security flaw that was exploited by triggering a module load and then exploiting a race condition in the kernel module load process), the commonly used exploit for this did not work on a SE Linux system because the user process was not permitted the socket access used to trigger the module load (it is believed that an attacker could have written a version of the exploit to work on a SE Linux system – but AFAIK no-one ever did so).

6 comments to How SE Linux Prevents Local Root Exploits

  • Dan Walsh did a good blog post about how SELinux constrained 2 samba vulnerabilities. In the comments, it also links to a Mambo exploit blocked by SELinux.

    One of those samba exploits actually could result in remote command execution if SELinux was not enabled.

  • Olaf van der Spek

    > On a machine running without SE Linux a compromise of a DHCP server is game-over as the server runs as root.

    There’s probably a good reason for running as root, but I’ve no idea what it would be.

    > setuid executables

    Why isn’t the setuid bit replaced by a set of privileges that are actually required instead of granting all those privileges at once via a single bit?

  • etbe

    Olaf: A DHCP server needs to receive UDP packets from machines that have no IP address and are not addressed to the server (the client generally doesn’t know the address of the server). Therefore it needs CAP_NET_RAW (which means root).

    As for setuid executables, there is work on creating set-cap executables but it isn’t going to go mainline in Linux for a while.

  • Olaf van der Spek

    Can’t the DHCP server (and other setuid executables) drop capabilities or root after it has used them?
    Receiving UDP broadcast packets doesn’t seem such an issue, I think it’s actually sending them that requires CAP_NET_RAW.

  • “As for setuid executables, there is work on creating set-cap executables but it isn’t going to go mainline in Linux for a while.”

    @etbe, you are actually wrong. Take a look at Andrew’s merge plans for 2.6.24:

    CTRL F search for ‘implement-file-posix-capabilities.patch’. It allows you to set CAP_NET_RAW on /bin/ping and strip the suid root bit off of it. Serge E. Hallyn, the author, was very responsive to comments and critiques. After sitting in -mm, this is finally being merged into mainline.

    You can get the userspace tools from either of these sites: # The original author of the userspace tools # The guy that wrote the kernel patch accepted into mainline’s site

  • etbe

    Olaf: You are correct that capabilities can be dropped, but this only works if capabilities are dropped correctly (there have been programs with bugs in this regard) and if the exploit can not happen before the capabilities are dropped (which has happened too).

    Jeff: That’s great, so once 2.6.24 is out the use of such features can be considered in distributions. Maybe in 3 years time we will have distributions using it.

    Also we will have some push-back from users about this. For example when programs that currently run as root are run as non-root then their data files need to be owned by non-root. If a program that is currently setuid is made setcap then when root runs it the result will be different from when non-root runs it – not an insurmountable problem but as we have seen with users turning off SE Linux it’s something that will cause acceptance problems.