Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 630830 - gnome-base/gdm: root privilege escalation via "chown" in pkg_postinst
Summary: gnome-base/gdm: root privilege escalation via "chown" in pkg_postinst
Status: CONFIRMED
Alias: None
Product: Gentoo Security
Classification: Unclassified
Component: Auditing (show other bugs)
Hardware: All Linux
: Normal critical (vote)
Assignee: Gentoo Security
URL:
Whiteboard: A1 [ebuild]
Keywords:
Depends on:
Blocks:
 
Reported: 2017-09-12 17:38 UTC by Michael Orlitzky
Modified: 2023-01-23 23:05 UTC (History)
6 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 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
      done

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
Comment 13 John Helmert III archtester Gentoo Infrastructure gentoo-dev Security 2022-08-11 02:44:33 UTC
Ping. Can we try removing the permissions hack again?
Comment 14 Pacho Ramos gentoo-dev 2022-12-14 10:27:31 UTC
(In reply to John Helmert III from comment #13)
> Ping. Can we try removing the permissions hack again?

I have retried but gdm still needs the ownership and access to /var/lib/gdm. Even if will create the directory itself with that permissions if I remove it and start gdm.

Also looking to Fedora, Debian and Arch, they are also allowing gdm to own /var/lib/gdm 

I am not sure then if this bug is really valid... or, at least, the concerns reported in the first comment would need to go to upstream as they expect /var/lib/gdm to be entirely accessible by gdm as its home directory. It is also used to save settings referring to the display manager.
Comment 15 Michael Orlitzky gentoo-dev 2022-12-14 13:36:15 UTC
(In reply to Pacho Ramos from comment #14)
> 
> I am not sure then if this bug is really valid... or, at least, the concerns
> reported in the first comment would need to go to upstream as they expect
> /var/lib/gdm to be entirely accessible by gdm as its home directory. It is
> also used to save settings referring to the display manager.

That's all fine. The only thing that's problematic is that our ebuild (as root) tries to "fix" those permissions whenever gdm is installed:

  1. The permissions shouldn't be wrong in the first place,
  2. Running chown in a directory you don't control is pretty much always 
     exploitable,
  3. The hack can't be that reliable anyway, since it relies on gdm being 
     installed *after* whatever creates those directories with the wrong
     permissions.

What we really need to know now is, what is creating e.g. /var/lib/gdm/.local as root? Once we know that, the best solution is probably to make it do so as gdm instead.
Comment 16 Pacho Ramos gentoo-dev 2022-12-15 19:47:38 UTC
For new installs today, I think that installing the .config/pulse with the right perms could work... but we would still need to fix the permissions of the parent dirs. Other distros are also doing that:
https://src.fedoraproject.org/rpms/gdm/blob/rawhide/f/gdm.spec#_277

I think that would work with a fresh install and a clean /var/lib/gdm... probably also for people updating from gdm ebuild versions that were running chown