Debian's x11-common init script weakness (CVE-2012-1093)

Tue, 20 Mar 2012 18:32:58 +0100
Tags: security

The init script issued from the x11-common Debian package is vulnerable to a traditional symlink attack that can lead to a privilege escalation while the package is being installed. This bug isn't very critical (except if you install x11-common for the very first time on a multi-user system), but I wanted to leave a note about it because the vulnerable code is quite common and could be found in your own scripts.

The code creates two temporary directories ($SOCKET_DIR and $ICE_DIR) in the following manner:

$ cat -n /etc/init.d/x11-common
[...]
11     set -e   
[...]
33       if [ -e $SOCKET_DIR ] && [ ! -d $SOCKET_DIR ]; then
34         mv $SOCKET_DIR $SOCKET_DIR.$$
35       fi
36       mkdir -p $SOCKET_DIR
37       chown root:root $SOCKET_DIR
38       chmod 1777 $SOCKET_DIR

A symlink attack looks impossible here as the script uses the "set -e" built-in command (the script aborts immediately when a command with a non-zero status is returned).

I mean, if $SOCKET_DIR is a symlink, we could think that the "mkdir -p" command at line 36 would fail (at least, this behavior was expected by developers). But this is wrong, "mkdir" with the "-p" option returns zero if the target already exits:

$ man mkdir
    [...]
        -p, --parents
               no error if existing, make parent directories as needed

So the only thing to exploit this is to place a link that doesn't match the condition at line 33 (i.e. a symlink that points to an existing directory), and wait for the package to be installed. In this case, a symlink to the "/etc" directory would allow the user to set the 1777 permission on this directory and create the "/etc/ld.preload" file in order to load malicious libraries into a set-uid process.

I reported this bug (BUG#661627), it was fixed with a very nice patch from jcristau in the version 1:7.6+12 of the x11-common package. Thanks to him.