Systemd "0day" Username Parsing Problem
Jul 03, 2017
Before anything else, I would just like to note that "0day" in the title refers to a Linux username that is literally 0day.
Over the last day or so, I and many others have learned of an interesting bug report submitted by the GitHub user mapleray on the systemd GitHub repository which notes that an unprivileged user created with a number at the beginning of the username, like 0day, being specified in a systemd service will cause the systemd service to start with root privileges.
Systemd developer Lennart Poettering replied with a negatively received response, closed the issue, and marked it as "Not A Bug", saying that usernames starting with a number are supposed to be invalid (as the bug report mentions in the post scriptum) and stating that it is a feature that systemd doesn't permit invalid usernames (a feature I personally agree with).
There are a few problems that actually make this a bug, though. First of all, it's trivial to make a user (even without knowing the expected Linux username syntax rules) with a number at the beginning of the username with the useradd command on Debian, a Linux distribution the uses systemd as its init system, as seen below.
The second problem is that instead of making the service fail at start, as systemd does with users that don't exist but have usernames that follow the Linux username syntax rules, systemd will ignore the "User=" field entirely and run the service as root. This is an unexpected action that can run a process meant to run as an unprivileged user as root instead, which is a security problem if the processes was not expected to run as root in the first place.
The biggest argument I have heard against this being a bug is that root is required to create a systemd service, so running as root isn't a problem. There is a flaw in this reasoning though. Chroot, for instance, should be run as root and not as an unprivileged user for security reasons, but once inside the chroot environment, privileges should drop from root to an unprivileged user, also for security reasons. If chroot ignored the privilege drop without the user knowing, processes inside the chroot environment can be run as root and someone that breaks into that chroot environment will be able to escape from the chroot environment with root privileges. It is important to know that root is essentially the "God mode" user in Linux and unexpected use of it can be very dangerous to a Linux system.
Poettering's dismissal of the problem as not a bug because users shouldn't be using a username that starts with a number is not encouraging for building trust in systemd's development. It shouldn't be up to the user to follow the rules properly so the developer doesn't need to handle these edge cases. A conversation about how parsing should work for the "User=" field or how big of an issue this bug will be for users is completely valid, but there are actual demonstrable cases of this being an unexpected feature that should be handled properly. In many programs, fuzzing (using invalid, unexpected, or randomly generated input like payloads/files/etc. . . to find unexpected issues or loopholes in the way the program functions with input) is a great way to find bugs to be patched. While the fuzzing input may be unexpected, it is still important for the bugs found by fuzzing to be patched and not dismissed, especially when security problems can arise.
In my personal opinion, a bug report should be made for useradd as well to properly handle Linux username handling, but a patch should also be issued for systemd to make a systemd services fail if the username syntax isn't as expected rather than unexpectedly running the service as root.