posted 2023-02-10
Prior to version 2.8.5, the Gentoo sys-apps/man-db package installed /usr/bin/mandb with owner:group man:man and setuid. The package also installed a cron job that would execute that file daily as root. Since the man user can modify the executable to do whatever he wants and also strip the setuid bit, he can gain root privileges every time the cron job is run.
Before version 2.8.5, the sys-apps/man-db package would install /usr/bin/mandb setuid and owned by the man user (the same user who owns the cache):
src_configure() { export ac_cv_lib_z_gzopen=$(usex zlib) local myeconfargs=( --docdir='$(datarootdir)'/doc/${PF} --with-systemdtmpfilesdir="${EPREFIX}"/usr/lib/tmpfiles.d --enable-setuid --enable-cache-owner=man ...
This allows the cache to be regenerated by anyone without messing up its permissions, since they will be regenerating it as the man user. However, the situation is exploitable if a privileged user executes the file. As proof, we check that the man user is allowed to strip off the setuid bit, and then replace /usr/bin/mandb with a malicious script:
root # su man -s /bin/sh
man $ chmod 755 /usr/bin/mandb
man $ cat < bad-script.sh > /usr/bin/mandb
If root now executes /usr/bin/mandb, then the malicious script will be run, allowing man to gain root. This is exacerbated by the fact that the same package installs a nightly cron job to do just that (these all run as root):
#!/bin/sh # Use same perms/settings as the ebuild. cachedir="/var/cache/man" if [ ! -d "${cachedir}" ]; then mkdir -p "${cachedir}" chown man:man "${cachedir}" chmod 0755 "${cachedir}" fi exec nice mandb --quiet
Thus there is an opportunity every day for the man user to alter the contents of /usr/bin/mandb, strip off its setuid bit, and gain root.
The sys-apps/man-db
ebuilds now pass --disable-setuid
to man-db's
./configure
script so that the executable is installed
sans setuid. Since typically only root will be regenerating the
cache, he is now responsible for dropping privileges. For example,
the modern cron job contains,
exec su man -s /bin/sh -c 'nice mandb --quiet' 2>/dev/null
which will safely drop privileges before regenerating the cache.
There were two reasons why the cron job was running as root in the first place:
Neither roadblock remains. Vixie-cron was removed a long time ago. Gentoo has also given up support for non-linux platforms, requiring systemd-tmpfiles to create temporary directories. As a result, a tmpfiles.d entry could be used to (re)create /var/cache/man, and a job dropped in /etc/cron.d could launch the man-db regeneration process directly as the man user. That would avoid the awkward su that has been annoying users ever since (bug #717128, bug #832182).