Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!

Bug 630830

Summary: gnome-base/gdm: root privilege escalation via "chown" in pkg_postinst
Product: Gentoo Security Reporter: Michael Orlitzky <mjo>
Component: AuditingAssignee: Gentoo Security <security>
Status: CONFIRMED ---    
Severity: normal CC: eva, expeditioneer, leio, pacho, security-audit, tranquility
Priority: Normal    
Version: unspecified   
Hardware: All   
OS: Linux   
Package list:
Runtime testing required: ---

Description Michael Orlitzky gentoo-dev 2017-09-12 17:38:02 UTC
(I haven't tested this because I'm not willing to switch to systemd to do it, but I'm fairly sure the following is exploitable)

The gdm ebuilds call "chown" on the live root filesystem in pkg_postinst:

  pkg_postinst() {
      chown gdm:gdm "${EROOT}var/lib/gdm" || ret=1
      for d in "${EROOT}var/lib/gdm/"{.cache,.config,.local}; do
          [[ ! -e "${d}" ]] || chown -R gdm:gdm "${d}" || ret=1

After the first "chown", the "gdm" user owns /var/lib/gdm, and he can replace any of the files or directories contained within it. For example, he can create /var/lib/gdm/.cache/foo as a hard link to /etc/passwd. The next recursive call to chown will then give ownership of /etc/passwd to the "gdm" user. That trick easily gains him root access on the machine.

That could be exploited the first time around with a race condition, but it's much easier to imagine the following:

  1. emerge gdm
  2. now the "gdm" user owns /var/lib/gdm
  3. he creates a hard link /var/lib/gdm/.cache/foo pointing to /root/.bashrc
  4. upgrade gdm (or simply emerge it again)
  5. "chown -R" now hits the hard link, and gives "gdm" root
Comment 1 Mart Raudsepp gentoo-dev 2018-08-15 04:03:09 UTC
How does the gdm user create anything when the ebuild or gdm code doesn't do it?
I mean, it already creates things in there as its XDG_DATA_HOME - it is its "home directory", but it is a system user that can't be logged in separately. This is a worry that privilege is escalated after somehow getting a program to create an appropriate symlink to gdm $HOME?
On my system I have in there: mesa shader cache, keyring control, dconf, ibus, fontconfig cache, dbus, pulseaudio configuration, color management config, some user desktop files barebones, etc.

What do you propose instead? The bug this is supposed to solve is noted above the chown code. There are concerns about gdm installing /var/lib from package at all via keepdir in a separate bug iirc, but this chown is about fixing up things mainly not from package manager control (the first chown takes care of package manager one, as there it's only coming from keepdir)
Comment 2 Mart Raudsepp gentoo-dev 2018-08-15 04:05:50 UTC
However the recursive chown was added to workaround a potential issue stemming from an ancient gdm-3.5 development release, so I guess we could just try to remove the recursive one and see if anything breaks for someone in a corner case...
Comment 3 Michael Orlitzky gentoo-dev 2018-08-15 13:10:54 UTC
(In reply to Mart Raudsepp from comment #1)
> How does the gdm user create anything when the ebuild or gdm code doesn't do
> it?

If there's a bug/exploit in GDM, then someone who exploits it can run code (and create stuff) as the "gdm" user. Then this bug lets the bad guy gain root rather than just the "gdm" account.

> What do you propose instead?
> ...
> However the recursive chown was added to workaround a potential issue stemming from an ancient gdm-3.5 development release, so I guess we could just try to remove the recursive one and see if anything breaks for someone in a corner case...

I agree based on the commit message that introduced the chown. If GDM and the ebuild are both doing their jobs, then the stuff in /var/lib/gdm should be created as "gdm" and thus have the right permissions already. I see that "fowners" is also used in src_install, so either the "fowners" or the non-recursive chown is redundant (I think users own their own home directories, so the non-recursive chown can probably go, too.)

If it turns out that the chown is still absolutely necessary, then I came up with some suggestions for that scenario a while back to make it as safe as possible:

* If possible, only operate on a specific list of paths. In other words,
  don't use --recursive just to save yourself some typing.

* If you don't have an explicit list of paths, then use find to collect the
  list of targets. The -user, -group, and -perm flags can ensure that you
  only find those paths that actually need fixing.

* Always use the --no-dereference flag with chown and chmod to avoid
  following symlinks created by an unprivileged user.

* If you're fixing incorrect ownership from an old version of your package,
  then you should know who the previous (wrong) owner is. Use the --from flag
  to chown to ensure that the old owner can't swap out one of his files with
  a hard link to a root-owned file.

* Tighten permissions in a top-down fashion. If you need to tighten the 
  permissions on /etc/foo and all of its contents, then tighten the
  permissions on /etc/foo first. That way, the operations that you perform
  on its contents are safer. If you're loosening permissions, do it the other
  way around.

* Check REPLACING_VERSIONS and fix permissions only when upgrading from a
  version that set them incorrectly.
Comment 4 Mart Raudsepp gentoo-dev 2018-08-17 00:39:18 UTC
I removed all this code removed in the 3.24.3-r1 (unrelated security) revbump as an ebuild cleanup in commit fa688468a75b6.
What should we do here now?
Comment 5 Mart Raudsepp gentoo-dev 2019-05-05 11:06:44 UTC
I am forced to add this back with gdm-3.30.3-r3 due to issues hit by users after having removed this.
The added back version passes --no-dereference. I bet we can do better then (specific find calls for a list or something?), but this is blocking stabilization of GNOME 3.30, along with real security fixes inside gdm-3.30 itself that couldn't be backported to previous stable.
Patches welcome how to handle this better in a future revbump.
Comment 6 Michael Orlitzky gentoo-dev 2019-05-05 19:05:47 UTC
What issue did users hit? There's some other bug that needs to be fixed: let's fix that instead of pushing out an exploitable ebuild to everyone again.
Comment 7 Mart Raudsepp gentoo-dev 2019-05-05 22:22:50 UTC
Users couldn't start GDM because the permissions were wrong. That's quite a show-stopper; of course if you can't start it, I guess there's nothing to exploit :D
Comment 8 Mart Raudsepp gentoo-dev 2019-05-05 22:31:09 UTC
Bug 669146 was one report. There have multiple different reports on various support forums that didn't have a corresponding bug entry.
Comment 9 Michael Orlitzky gentoo-dev 2019-05-05 22:39:18 UTC
To quote from that bug,

  I checked the permissions and found out that /var/lib/gdm was owned by
  user gdm, but /var/lib/gdm/.local was owned by root.

What is creating ".local" as root? That situation itself is almost certainly exploitable, because root operates in a user-owned directory. Whatever is responsible should be e.g. dropping privileges first, or using some other directory (like /root/.local).

In other words: there's some other bug that's making *this* bug necessary. We should fix them both instead of keeping them both.
Comment 10 Mart Raudsepp gentoo-dev 2019-05-05 22:45:05 UTC
I have no idea what causes such a situation. If I knew, I would have tried to fix it.
Comment 11 Robin Johnson archtester Gentoo Infrastructure gentoo-dev Security 2020-04-03 23:16:26 UTC
Unrestricting and reassigning to security@ per bug #705894
Comment 12 Robin Johnson archtester Gentoo Infrastructure gentoo-dev Security 2020-04-03 23:18:25 UTC
unrestricting per bug 705894