Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 630810 - app-misc/uptimed: root privilege escalation via "chown -R" in pkg_postinst
Summary: app-misc/uptimed: root privilege escalation via "chown -R" in pkg_postinst
Status: CONFIRMED
Alias: None
Product: Gentoo Security
Classification: Unclassified
Component: Auditing (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Gentoo Security
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-09-12 14:51 UTC by Michael Orlitzky
Modified: 2020-05-21 23:05 UTC (History)
2 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 2017-09-12 14:51:17 UTC
The uptimed ebuilds call chown recursively on the live root filesystem in pkg_postinst:

  pkg_postinst() {
      einfo "Fixing permissions in /var/spool/${PN}"
      chown -R uptimed:uptimed /var/spool/${PN}
      ...

The uptimed user can place a hard link in /var/spool/uptimed pointing to a sensitive root-owned file, and the next time that uptimed is emerged, that file will be given to the uptimed user. For example,

  1. emerge uptimed
  2. sudo su -s /bin/sh -c 'ln /etc/passwd /var/spool/uptimed/x' uptimed
  3. emerge uptimed
  4. the file /etc/passwd is owned by uptimed:uptimed
Comment 1 Lars Wendler (Polynomial-C) gentoo-dev 2019-04-20 20:34:29 UTC
commit 8029ba6c8920e379ea1f5f71afc297bfd30925b3
Author: Lars Wendler <polynomial-c@gentoo.org>
Date:   Sat Apr 20 22:31:38 2019

    app-misc/uptimed: Attempt to fix privilege escalation in pkg_postinst

    Bug: https://bugs.gentoo.org/630810
    Package-Manager: Portage-2.3.64, Repoman-2.3.12
    Signed-off-by: Lars Wendler <polynomial-c@gentoo.org>
Comment 2 Michael Orlitzky gentoo-dev 2019-04-21 15:31:20 UTC
Unfortunately this suffers from the same problem:

-       chown -R uptimed:uptimed /var/spool/${PN}
+       local spooldir="/var/spool/${PN}"
+       if [[ -d "${spooldir}" ]] ; then
+               einfo "Fixing permissions in ${spooldir}"
+               find ${spooldir} -type f -print0 \
+                       | xargs --null chown uptimed:uptimed || die
+       fi

In fact, symlinks will work now too (not just hard links). What is it supposed to fix? Maybe I can suggest a better way.
Comment 3 Lars Wendler (Polynomial-C) gentoo-dev 2019-04-24 08:52:15 UTC
(In reply to Michael Orlitzky from comment #2)
> Unfortunately this suffers from the same problem:
> 
> -       chown -R uptimed:uptimed /var/spool/${PN}
> +       local spooldir="/var/spool/${PN}"
> +       if [[ -d "${spooldir}" ]] ; then
> +               einfo "Fixing permissions in ${spooldir}"
> +               find ${spooldir} -type f -print0 \
> +                       | xargs --null chown uptimed:uptimed || die
> +       fi
> 
> In fact, symlinks will work now too (not just hard links). What is it
> supposed to fix? Maybe I can suggest a better way.


I don't see how this suffers from the same problem. There's now a test if spooldir is a directory (and no symlink), and the find call only operates on files.
Comment 4 Michael Orlitzky gentoo-dev 2019-04-24 11:39:50 UTC
(In reply to Lars Wendler (Polynomial-C) from comment #3)
> 
> I don't see how this suffers from the same problem. There's now a test if
> spooldir is a directory (and no symlink), and the find call only operates on
> files.

The directory was never the problem, it's a file *in* the directory. The same thing works:

  sudo su -s /bin/sh -c 'ln /etc/passwd /var/spool/uptimed/x' uptimed

The uptimed user creates a link called "x" in /var/spool/uptimed pointing to a file of his choosing. The call to chown then gives him ownership of that file.
Comment 5 Lars Wendler (Polynomial-C) gentoo-dev 2019-04-24 11:45:06 UTC
(In reply to Michael Orlitzky from comment #4)
> (In reply to Lars Wendler (Polynomial-C) from comment #3)
> > 
> > I don't see how this suffers from the same problem. There's now a test if
> > spooldir is a directory (and no symlink), and the find call only operates on
> > files.
> 
> The directory was never the problem, it's a file *in* the directory. The
> same thing works:
> 
>   sudo su -s /bin/sh -c 'ln /etc/passwd /var/spool/uptimed/x' uptimed
> 
> The uptimed user creates a link called "x" in /var/spool/uptimed pointing to
> a file of his choosing. The call to chown then gives him ownership of that
> file.

But the chown does not act on the symlink because find only hands over files to xargs and that calls chown without -R parameter...
Comment 6 Michael Orlitzky gentoo-dev 2019-04-24 11:57:44 UTC
(In reply to Lars Wendler (Polynomial-C) from comment #5)
> 
> But the chown does not act on the symlink because find only hands over files
> to xargs and that calls chown without -R parameter...

Contrary to all common sense, chown follows symlinks and hardlinks by default.
Comment 7 Lars Wendler (Polynomial-C) gentoo-dev 2019-04-24 12:11:30 UTC
Sorry, you're right. Hardlinks are the real issue. Dunno how to not make chown act on them...
Comment 8 Michael Orlitzky gentoo-dev 2019-04-24 12:20:12 UTC
There are a lot of half-fixes that you can pile on:

  * Use the -user, -group, and -perm flags to "find" so that you only find
    files that need fixing.

  * Add --no-dereference to chown to keep it from following symlinks (there's
    a race condition in the implementation, but it's as small as you can make
    it).

  * Use the --from flag with chown to ensure that an attacker can't swap one
    file for a link with a different owner/group.

  * If you're fixing something during an upgrade, you can check the
    REPLACING_VERSIONS variable to ensure that you don't mess with things
    during a fresh install.

Ultimately the right answer depends on what you're trying to fix though.
Comment 9 Lars Wendler (Polynomial-C) gentoo-dev 2019-04-24 12:25:24 UTC
commit 559aeb8ce8d3fe7c6c5f8618f93995252d1683fd
Author: Lars Wendler <polynomial-c@gentoo.org>
Date:   Wed Apr 24 14:20:02 2019

    app-misc/uptimed: Another attempt to fix privilege escalation
    
    Bug: https://bugs.gentoo.org/630810
    Package-Manager: Portage-2.3.64, Repoman-2.3.12
    Signed-off-by: Lars Wendler <polynomial-c@gentoo.org>


I'm using

  find ${spooldir} -type f -links 1 

now which should neither hand over symlinks nor hardlinks to xargs.
Comment 10 Michael Orlitzky gentoo-dev 2019-04-24 12:27:55 UTC
> 
> I'm using
> 
>   find ${spooldir} -type f -links 1 
> 
> now which should neither hand over symlinks nor hardlinks to xargs.

If the uptimed user creates 1,000,000 empty files in that directory, he will have several minutes between the "find" call and the "chown" call to replace the last one with a link.
Comment 11 Robin Johnson archtester Gentoo Infrastructure gentoo-dev Security 2020-04-03 23:16:33 UTC
Unrestricting and reassigning to security@ per bug #705894
Comment 12 Robin Johnson archtester Gentoo Infrastructure gentoo-dev Security 2020-04-03 23:18:11 UTC
unrestricting per bug 705894
Comment 13 Sam James gentoo-dev Security 2020-05-21 22:50:19 UTC
(In reply to Michael Orlitzky from comment #10)
> > 
> > I'm using
> > 
> >   find ${spooldir} -type f -links 1 
> > 
> > now which should neither hand over symlinks nor hardlinks to xargs.
> 
> If the uptimed user creates 1,000,000 empty files in that directory, he will
> have several minutes between the "find" call and the "chown" call to replace
> the last one with a link.

Can we ask the user to make the changes, if necessary, instead?
Comment 14 Michael Orlitzky gentoo-dev 2020-05-21 23:05:50 UTC
(In reply to Sam James (sec padawan) from comment #13)
> 
> Can we ask the user to make the changes, if necessary, instead?

What problem is this pkg_postinst() intended to fix? If the permissions are perpetually wrong, then there's a bug somewhere else, and asking the user to fix them repeatedly is just punting the problem to him or her. We should fix the thing that creates files with the wrong permissions.

If the permissions were wrong once and have never been wrong since, we can probably just delete this code now since the bug is so old.

(For future reference, though, there are suggestions on my pkg_postinst article for how to minimize the risk of a one-time fix.)