Remediation Guides

How to Fix CVE-2021-4034 (PwnKit) in polkit pkexec

26 September 2026 8 min read

CVE-2021-4034, known as PwnKit, is a memory corruption bug in polkit’s pkexec that lets any local user become root. Fix it by updating polkit (policykit-1 on Debian and Ubuntu) to your distribution’s patched package, such as USN-5252-1 or RHSA-2022:0267. No reboot is needed. Until then, chmod 0755 /usr/bin/pkexec removes the attack path.

What the scanner is actually detecting

Nessus reports PwnKit through distribution-specific local checks. Each plugin compares the installed polkit packages against the fixed build in one vendor advisory, so the finding only appears in credentialed (SSH) scans. The four plugins below all map to CVE-2021-4034 and the same fix.

Nessus plugin Finding title Family
157112 Ubuntu 18.04 LTS / 20.04 LTS : PolicyKit vulnerability (USN-5252-1) Ubuntu Local Security Checks
157135 RHEL 8 : polkit (RHSA-2022:0266) Red Hat Local Security Checks
157071 RHEL 7 : polkit (RHSA-2022:0270) Red Hat Local Security Checks
157156 CentOS 8 : polkit (CESA-2022:0267) CentOS Local Security Checks

The Ubuntu plugin checks policykit-1 and the related libpolkit-* and gir1.2-polkit-1.0 packages. The RHEL and CentOS plugins check polkit, polkit-devel and polkit-docs, plus polkit-libs on RHEL 8 and CentOS 8. Tenable states that the RHEL 7 and CentOS 8 plugins rely on the package’s self-reported version rather than testing the flaw directly. Tenable keeps the full plugin list for CVE-2021-4034, which includes other distributions.

The bug itself: pkexec does not handle being started with an empty argument list (argc of 0). It then reads and writes past the end of argv into the environment. Because pkexec is installed setuid root, Qualys showed that this lets an attacker reintroduce an unsafe environment variable (they used GCONV_PATH) that the loader normally strips, and get code loaded as root. Qualys traced the flaw back to the first version of pkexec in May 2009.

Real-world risk

This is a local privilege escalation. CVSS v3 rates it 7.8, and an attacker must already run commands on the host as some user. It is not reachable over the network on its own. What makes it a priority:

  • Qualys reported exploiting default installations of Ubuntu, Debian, Fedora and CentOS, and noted other distributions are probably exploitable too.
  • Tenable lists public exploits for this issue in Metasploit, CANVAS and Core Impact.
  • CVE-2021-4034 is in the CISA Known Exploited Vulnerabilities catalog, with a federal due date of July 18, 2022. Our CISA KEV catalog explainer covers what that listing should mean for your patch priority.

The practical risk is highest where untrusted or semi-trusted code runs: multi-user shell hosts, CI runners, and servers with web applications whose service account could be compromised. On a single-purpose server with no local users, exposure is lower, but the fix is a small package update with no restart, so there is little reason to defer it.

How to confirm it on the host

Check whether polkit is installed and at which package version:

# Debian, Ubuntu
dpkg -l '*polkit*'
dpkg-query -W policykit-1

# RHEL, CentOS
rpm -qa 'polkit*'

Distribution fixes are backported, so the upstream version (0.105 on Ubuntu, 0.112 on RHEL 7, 0.115 on RHEL 8) does not change. Look for the CVE in the package changelog instead:

# Debian, Ubuntu
zgrep CVE-2021-4034 /usr/share/doc/policykit-1/changelog.Debian.gz

# RHEL, CentOS
rpm -q --changelog polkit | grep CVE-2021-4034

Confirm that pkexec is present and still setuid root. A mode of 4755 means the attack path is open on an unpatched package:

stat -c '%a %U %n' /usr/bin/pkexec

If you suspect the host was already abused, Qualys noted that their exploit leaves one of two messages in the logs: “The value for the SHELL variable was not found the /etc/shells file” or “The value for environment variable […] contains suscipious content” (the misspelling comes from pkexec itself):

# Debian, Ubuntu
zgrep -E "SHELL variable was not found|suscipious content" /var/log/auth.log*

# RHEL, CentOS
zgrep -E "SHELL variable was not found|suscipious content" /var/log/secure*

Qualys also stated the bug can be exploited without leaving these traces, so an empty result is not proof of a clean host.

How to fix it

Install the fixed package for your release. Any later package from the same repository also contains the fix.

Platform Advisory Fixed package
Ubuntu 20.04 LTS USN-5252-1 policykit-1 0.105-26ubuntu1.2
Ubuntu 18.04 LTS USN-5252-1 policykit-1 0.105-20ubuntu0.18.04.6
Ubuntu 16.04 LTS (Ubuntu Pro) USN-5252-2 policykit-1 0.105-14.1ubuntu0.5+esm1
Debian 11 (bullseye) DSA-5059-1 policykit-1 0.105-31+deb11u1
Debian 10 (buster) DSA-5059-1 policykit-1 0.105-25+deb10u1
RHEL 8 RHSA-2022:0267 polkit-0.115-13.el8_5.1
RHEL 8.4 EUS RHSA-2022:0266 polkit-0.115-11.el8_4.2
RHEL 7 RHSA-2022:0274 polkit-0.112-26.el7_9.1
RHEL 7.3 AUS RHSA-2022:0270 polkit-0.112-12.el7_3.1

Note that the advisory in a plugin title is not always the one for your update stream. RHSA-2022:0266 and RHSA-2022:0270 are Extended Update Support and Advanced Update Support advisories. Red Hat’s bulletin RHSB-2022-001 lists the full errata set, including other EUS, AUS and SAP streams and RHEL 6 ELS. What matters is that the installed build is at or above the fixed build for the stream the host is subscribed to.

Ubuntu and Debian

sudo apt update
sudo apt install --only-upgrade policykit-1 libpolkit-agent-1-0 libpolkit-backend-1-0 libpolkit-gobject-1-0
dpkg-query -W policykit-1

With --only-upgrade, apt skips any package in the list that is not installed. If dpkg -l '*polkit*' also shows -dev or gir1.2-polkit-1.0 packages, add them so every package the plugin checks ends up at the fixed version. Ubuntu notes that a standard system update (sudo apt upgrade) applies the fix as well.

RHEL and CentOS

# RHEL 7
sudo yum update 'polkit*'

# RHEL 8
sudo dnf update 'polkit*'

rpm -qa 'polkit*'

Plugin 157156 compares CentOS 8 hosts against CESA-2022:0267, the CentOS rebuild of RHSA-2022:0267. CentOS Linux 8 reached end of life on December 31, 2021, so treat any CentOS 8 host as a migration item, not only a patch item.

If you cannot patch yet

Qualys recommended removing the setuid bit as a temporary mitigation:

sudo chmod 0755 /usr/bin/pkexec

Red Hat does not recommend this, because pkexec then stops working for legitimate use. It publishes a SystemTap script in RHSB-2022-001 instead, which blocks pkexec when called with an empty argument and does not work on Secure Boot enabled systems. Either way, this is a stopgap: the Nessus plugins check package versions, so the finding stays open until the package is updated.

How to verify the fix and rescan

  1. Confirm the package version against the table above with dpkg-query -W policykit-1 or rpm -qa 'polkit*', and check that the changelog lists CVE-2021-4034.
  2. Run stat -c '%a %U %n' /usr/bin/pkexec. If you applied the chmod mitigation earlier, restore the original mode after patching with sudo chmod 4755 /usr/bin/pkexec if the update did not already reset it.
  3. Rerun the credentialed Nessus scan. Plugins 157112, 157135, 157071 or 157156 should no longer report on the host. In the Nessus Scan Information output (plugin 19506), confirm that credentialed checks show yes; if the SSH login failed, local plugins never run and the finding disappears for the wrong reason. Our Linux authenticated scan guide covers the SSH and privilege settings.

Red Hat states there is no need to restart any service or reboot after applying the fix. pkexec is started fresh each time, so the patched binary is used immediately.

What can break and how to roll back

The polkit update is a small, targeted package change and rarely causes trouble. The mitigation is the part more likely to cause problems: with the setuid bit removed, anything that calls pkexec to run a command as root (admin scripts, some desktop tools) fails until the bit is restored.

To undo the mitigation:

sudo chmod 4755 /usr/bin/pkexec

To roll back the package on RHEL or CentOS, find and undo the transaction:

sudo yum history list polkit
sudo yum history undo <transaction-id>

On Debian or Ubuntu, reinstall a specific earlier version if your mirror still carries it: sudo apt install policykit-1=<previous-version>. Rolling back reopens CVE-2021-4034, so only do it long enough to fix whatever broke.

Common false positive reasons

  • Backported fixes and version comparison. Patched packages keep the old upstream version (for example 0.105 on Ubuntu). A tool that compares only upstream versions can still flag a patched host. When the distribution package matches the table and the changelog lists CVE-2021-4034, the host is fixed. See why backported patches cause false positives for how to document this.
  • Stale results. The report predates the update, or the rescan ran without working credentials.
  • Libraries left behind. Updating only policykit-1 or polkit while a libpolkit-*, polkit-libs or -devel package stays old keeps the plugin firing. This is a real finding against that package, not a false positive.

A host with the chmod mitigation in place is also not a false positive. The vulnerable package is still installed, so record it as mitigated with a patch date rather than closing it.

FAQ

Can PwnKit be exploited remotely?

No. The attacker needs a local shell first, for example through a compromised web application, stolen SSH credentials or a low-privileged account.

Do I need to reboot after updating polkit?

No. Red Hat states that no service restart or reboot is needed after applying the fix.

Does chmod 0755 close the Nessus finding?

No. The distribution plugins check package versions, not file permissions. The finding closes only after the fixed package is installed.

Is a host without polkit affected?

No. The flaw is in pkexec, which ships with polkit. If no polkit package is installed, there is nothing to exploit and the distribution plugins should not report it.

Tracking this finding across many hosts

On a large Linux fleet, the hard part is proving every host is closed, not patching one. SITEY, a self-hosted vulnerability management platform, imports Nessus results from an uploaded .nessus export and supports per-finding retest for Nessus. Its AI can draft host-specific remediation scripts that run only after human approval, deployed by SITEY agents on Linux endpoints, followed by a retest to verify closure.

Sources

SITEY closes the loop, not just the report.Discover, validate, fix and verify in your own infrastructure.

See pricing