Our sys-apps/man-db package installs the /usr/bin/mandb program setuid and setgid with owner/group "man". We also install a daily cron job from ${FILESDIR}/man-db.cron that runs as root and executes, exec nice mandb --quiet This can be exploited by the "man" user to gain root privileges. For example, the "man" user can simply strip off the setuid/setgid bits: # su man -s /bin/sh -c 'chmod 755 /usr/bin/mandb' Now when "mandb" is run in the cron job, it will run with root privileges. But the owner of /usr/bin/mandb has not changed, so the "man" user can write to it because he owns it: # su man -s /bin/sh -c 'cat < bad-script.sh > /usr/bin/mandb' Whenever the cron job runs again, the "man" user gains root.
Mh, this sounds like bug 602588...
(In reply to Thomas Deutschmann from comment #1) > Mh, this sounds like bug 602588... I saw that, but the gist of this one is more "the executable shouldn't be owned by 'man' to begin with." The fact that the cron job makes it easy to exploit is only adding insult to injury. If root (or another privileged user) was ever going to run /usr/bin/mandb for any reason, then the "man" user could swap out its contents beforehand.
See the following upstream commits. Separate cache owner from --enable-setuid option: https://git.savannah.gnu.org/cgit/man-db.git/commit/src/Makefile.am?id=0f8b5518949866075c25787bdc4e9c064597c21e Eliminate dangerous setgid-root directories: https://git.savannah.gnu.org/cgit/man-db.git/commit/src/Makefile.am?id=31552334cecee82809059ec598a37d9ea82683f0 So this looks like being inteded by upstream. CCing Colin so he can perhaps give some more input into this.
I don't think those commits are especially related, except perhaps insofar as they describe existing practice. This sort of thing is indeed a problem with having setuid-to-non-root executables that might be run as root: such a setup inherently means that root has to trust the user that owns the executable. I can see a few non-exclusive options: 1) Make mandb setuid root instead, and add code at the start of main() (or maybe in init_security() or something) to drop to MAN_OWNER if necessary. 2) Mitigate the bug by making the cron job run as the man user rather than root; at least then it isn't *guaranteed* that mandb will be run as root. (Note that Debian's cron jobs have run as the man user for at least 17 years.) 3) Stop installing mandb setuid by default. Option 1 might be a good idea, and is probably the only way to preserve the setuid setup while immunising against this bug. On the other hand, it adds a bit more attack surface and would have to be done carefully. Option 2 seems to have no obvious downsides. Assuming it works in the Gentoo setup, you surely ought to do this even if it isn't a complete fix for this bug. Option 3 is almost certainly the right long-term fix.
The bug has been referenced in the following commit(s): https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=59d4f75abd7dc6b691a95b5447133922ff09ea3f commit 59d4f75abd7dc6b691a95b5447133922ff09ea3f Author: Lars Wendler <polynomial-c@gentoo.org> AuthorDate: 2019-01-06 15:10:21 +0000 Commit: Lars Wendler <polynomial-c@gentoo.org> CommitDate: 2019-01-06 15:11:41 +0000 sys-apps/man-db: Synced live ebuild. Attempt to fix root privilege escalation. Bug: https://bugs.gentoo.org/662438 Bug: https://bugs.gentoo.org/666404 Package-Manager: Portage-2.3.54, Repoman-2.3.12 Signed-off-by: Lars Wendler <polynomial-c@gentoo.org> sys-apps/man-db/man-db-9999.ebuild | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=afd4c6fd6980ca985387496bfe16588e9a387d1c commit afd4c6fd6980ca985387496bfe16588e9a387d1c Author: Lars Wendler <polynomial-c@gentoo.org> AuthorDate: 2019-01-06 15:04:51 +0000 Commit: Lars Wendler <polynomial-c@gentoo.org> CommitDate: 2019-01-06 15:11:40 +0000 sys-apps/man-db: Bump to version 2.8.5 Attempt to fix root privilege escalation. Bug: https://bugs.gentoo.org/662438 Closes: https://bugs.gentoo.org/666404 Package-Manager: Portage-2.3.54, Repoman-2.3.12 Signed-off-by: Lars Wendler <polynomial-c@gentoo.org> sys-apps/man-db/Manifest | 1 + sys-apps/man-db/files/man-db.cron-r1 | 11 ++++ sys-apps/man-db/man-db-2.8.5.ebuild | 121 +++++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+)
Michael, please check if this attempt is sufficient to get rid of this root escalation issue.
(In reply to Lars Wendler (Polynomial-C) from comment #6) > Michael, please check if this attempt is sufficient to get rid of this root > escalation issue. In the past, I'm almost certain that portage would not change the owner or group of a file that already exists during merge. So, I was expecting /usr/bin/mandb to still be "man:man" after an upgrade. Good news: it isn't! Bad news: I don't know why, or if we can rely on that happening. I'm going to ask around to see if something changed in portage to make this reliable. But the fix generally looks good to me. In the future you might want to create /var/cache/man in src_install, so that you don't have to do it in both the cron job and pkg_preinst, and you don't have to chown/chmod it every time (this can also be dangerous if /var/cache isn't owned by root). Then, instead of the shell script cron job that we have now, you could put something simpler in /etc/cron.d: <minute> <hour> * * * man mandb --quiet
(In reply to Michael Orlitzky from comment #7) > > In the past, I'm almost certain that portage would not change the owner or > group of a file that already exists during merge. So, I was expecting > /usr/bin/mandb to still be "man:man" after an upgrade. > This still happens for directories but not for files. I tested back to portage-2.3.6, so we'd best assume the simplest explanation: I'm remembering wrong, and the ownership of *files* will be updated.
(In reply to Michael Orlitzky from comment #7) > > But the fix generally looks good to me. In the future you might want to > create /var/cache/man in src_install, so that you don't have to do it in > both the cron job and pkg_preinst, and you don't have to chown/chmod it > every time (this can also be dangerous if /var/cache isn't owned by root). No can do as this would put the content of /var/cache/man into the package's content which we wanna avoid (by doing it in pkg_preinst). > Then, instead of the shell script cron job that we have now, you could put > something simpler in /etc/cron.d: > > <minute> <hour> * * * man mandb --quiet That sounds like a good idea. Care to file a separate bug for that?
CVE requested