michael orlitzky

CVE-2017-11746: Tenshi privilege escalation via PID file manipulation

posted 2017-07-30

Tenshi (log monitoring tool)
Inverse Path (F-Secure)
Versions affected
0.15 and earlier
Published on
Fixed in
commits 46b0148 and d0e7f28, version 0.16
Bug report
Andrea Barisani who fixed several other issues and got a new release out to help fix this one.


Tenshi 0.15 and earlier creates a tenshi.pid file after dropping privileges to a non-root account. This is exploitable by that non-root account to kill root processes, because the init script supplied by Tenshi (and many distributions) will send a SIGTERM to the contents of the PID file upon stopping the service.


The purpose of the PID file is to hold the PID of the running daemon, so that later it can be stopped, restarted, or otherwise signalled (many daemons reload their configurations in response to a SIGHUP). To fulfil that purpose, the contents of the PID file need to be trustworthy. If the PID file is writable by a non-root user, then he can replace its contents with the PID of a root process. Afterwards, any attempt to signal the PID contained in the PID file will instead signal a root process chosen by the non-root user (a vulnerability).

This is commonly exploitable by init scripts that are run as root and which blindly trust the contents of their PID files. Tenshi itself ships a few such init scripts: tenshi.debian-init, tenshi.suse-init, etc.


An example of a problematic scenario involving an init script would be,

  1. I run /etc/init.d/tenshi start to start the daemon.
  2. tenshi drops to the tenshi user.
  3. tenshi writes its PID file, now owned by the tenshi user.
  4. Someone compromises the daemon, which processes untrusted input.
  5. The attacker is generally limited in what he can do because the daemon doesn't run as root. However, he can write “1” into the PID file, and he does.
  6. I run /etc/init.d/tenshi stop to stop the daemon while I investigate the weird behavior resulting from the hack.
  7. The machine reboots, because I killed PID 1 (this is normally restricted to root).


The problem is avoided by creating the PID file as root, before dropping privileges. Init script writers should relocate the PID file to /run or a similar root-owned directory.