-
Notifications
You must be signed in to change notification settings - Fork 571
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CVE-2017-16933: root privilege escalation via prepare-dirs (init script and systemd service file) #5793
Comments
For systemd we should consider fixing this with RuntimeDirectory and the other systemd settings, but this won't fix initd. |
There's also the tmpfiles.d option with systemd, but the same caveat applies. OpenRC now supports tmpfiles, but classic SysV-style init never will. In my first comment, I mentioned that letting the end user change
A priori the second option is dangerous because you don't know what the user is going to set those variables to, and it isn't advertised that you're going to be calling There's also a more subtle problem... if the user points (say) the log file variable to an existing file, you have to be careful to set the permissions in a safe order. For example, it's not safe to So tl;dr I would remove any options that require you to fix ownership or permissions at runtime as root. Having to recompile to change things is annoying, but at least then the ownership/permissions can be set in the build directory (on the newly-built files) and not on the live filesystem. |
How do other applications solve this issue? I would believe this isn't exclusive to Icinga. |
Well, I've found about 20 or so that do the same thing and therefore have the same exploit... I thought about this really hard a year ago when I found the first one, and the best that I could come up with was "don't do that" for runtime-switchable users and "state" directories. We've fixed a bunch of init scripts in Gentoo by eliminating those options, although we have an advantage in the distro: we can create a separate user and run |
We should use |
The For example, Just like Anyway, what I'm getting at is that, since we don't know what the value of e.g. |
One thing to note if the application should "crash" if permissions are wrong: We need better error messages and a cold startup permission check to do so. The idea is to allow features register required directories and permissions, and check them as icinga user. If anything is wrong, an error will be logged to stderr or the log with EXIT_FAILURE. |
@orlitzky You I are right, I had hoped install would fail if the directory exists (which in hindsight makes the test void), alas it does not but overwrites Addendum: This means we need to move these into the core, and create them after we dropped our permissions. |
If you have a fix in mind for systemd I'd like to consume it. |
@lazyfrosch Broken link |
Sorry was testing a Trello integration, please ignore... |
Closed #5850 |
The
etc/initsystem/prepare-dirs
file callschown
unsafely, leading to a root exploit for the$ICINGA2_USER
. The tl;dr is that it's never safe to call chown as root, unless the target and all directories above it are controlled wholly by root.A few uses of
chown
inprepare-dirs
are exploitable; here's an example:The first line gives away ownership of the directory containing the
$ICINGA2_PID_FILE
, and the next line callschown
on that file. The exploit is that, after the first line executes, the$ICINGA2_USER
can simply replace$ICINGA2_PID_FILE
with a link (sym or hard) to a root-owned file. The call tochown
will then change ownership of the link's target. That is easily exploitable to gain root, by taking ownership of e.g./etc/passwd
or root's.bashrc
file.To exploit this the first time the service is started, you need to take advantage of the race condition to create a link before the
-f
test is executed. However, there's a much easier scenario: if the service is started, stopped, and started again (even across reboots, for persistent directories), then the-f
test will succeed, and call chown on a path that has been controlled by$ICINGA2_USER
since the first time the service was started.As for the fix, I would entirely eliminate the ability to change the value of
$ICINGA2_USER
and$ICINGA2_GROUP
at runtime, since there is no safe way for you to fix the permissions after it is changed. Once those variables are eliminated, you don't need to callchown
on the directories or files: the directories can be created with the correct ownership bymake install
, and the files will be owned by the user who creates them (namely the icinga runtime user, who will be the one writing to them, and that user will never change).If you would rather keep those variables, just let the init/service script crash if the permissions are wrong. Users will have to be responsible for fixing the existing permissions if they make a major change like switching an in-use UID/GID on a live system. (This is not mere sadism on my part; there really is no safe way to automate the necessary changes.)
This affects both the init script and systemd service file:
icinga2/etc/initsystem/icinga2.init.d.cmake
Line 65 in df10d2a
icinga2/etc/initsystem/icinga2.service.cmake
Line 8 in df10d2a
The text was updated successfully, but these errors were encountered: