Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 662438 - sys-apps/man-db: root privilege escalation through setuid executable and cron job
Summary: sys-apps/man-db: root privilege escalation through setuid executable and cron...
Status: CONFIRMED
Alias: None
Product: Gentoo Security
Classification: Unclassified
Component: Vulnerabilities (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Gentoo Security
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-07-29 20:42 UTC by Michael Orlitzky
Modified: 2020-04-11 18:49 UTC (History)
3 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Orlitzky gentoo-dev 2018-07-29 20:42:23 UTC
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.
Comment 1 Thomas Deutschmann gentoo-dev 2018-07-29 22:25:48 UTC
Mh, this sounds like bug 602588...
Comment 2 Michael Orlitzky gentoo-dev 2018-07-29 23:06:50 UTC
(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.
Comment 3 Lars Wendler (Polynomial-C) (RETIRED) gentoo-dev 2018-09-17 12:27:24 UTC
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.
Comment 4 Colin Watson 2018-09-17 13:00:04 UTC
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.
Comment 5 Larry the Git Cow gentoo-dev 2019-01-06 15:11:53 UTC
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(+)
Comment 6 Lars Wendler (Polynomial-C) (RETIRED) gentoo-dev 2019-01-06 15:13:23 UTC
Michael, please check if this attempt is sufficient to get rid of this root escalation issue.
Comment 7 Michael Orlitzky gentoo-dev 2019-01-06 16:09:49 UTC
(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
Comment 8 Michael Orlitzky gentoo-dev 2019-01-07 16:04:57 UTC
(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.
Comment 9 Lars Wendler (Polynomial-C) (RETIRED) gentoo-dev 2019-01-11 09:02:34 UTC
(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?