← Back to Feed CACHED · 2026-10-24 11:36:23 · CACHE_KEY CVE-2022-22706
CVE-2022-22706 · CWE-119 · Disclosed 2022-03-03

Arm Mali GPU Kernel Driver read-only page write via incomplete flag check in kbase_jd_user_buf_pin_pages

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

The GPU bouncer checks your VIP wristband but never looks at your face, so anyone who flashes the right color walks into the vault

CVE-2022-22706 is a local privilege escalation in Arm's Mali GPU kernel driver — the graphics component shipping inside roughly 40% of all Android devices. The bug lives in kbase_jd_user_buf_pin_pages(), which pins user-supplied memory pages for GPU operations. When deciding whether a page should be writable, the function checks only the KBASE_REG_GPU_WR flag and ignores KBASE_REG_CPU_WR. An unprivileged app can import a read-only mapping (e.g. /etc/passwd or a shared library) through the Mali ioctl interface, trigger the page-pinning path, and silently promote that mapping to writable. From there, the attacker overwrites the page cache of sensitive files — blanking root's password hash or injecting code into a privileged process's loaded library — and escalates to root. Affected driver ranges are enormous: Midgard r26p0–r31p0, Bifrost r0p0–r35p0, and Valhall r19p0–r35p0. Fixed versions are Midgard r32p0 and Bifrost/Valhall r36p0, but the Android ecosystem didn't ship the fix until the June 2023 security patch level (2023-06-05), leaving a gap of over a year after Arm's own fix.

Arm assigned this HIGH / 7.8 and CVSS agrees the local-access prerequisite keeps it out of CRITICAL on paper. In practice the vendor score *understates* the operational risk. Google TAG confirmed it was weaponized as an n-day in a spyware campaign linked to Variston, delivered via SMS to Samsung handsets in the UAE in December 2022 — months before Android OEMs shipped the patch. CISA added it to the KEV catalog in March 2023. A compiled C proof-of-concept is public on GitHub (byt3quester/CVE-2022-22706-poc), and STAR Labs published a full exploit walkthrough in 2025. The sheer scale of the unpatched population — billions of devices, many of which will *never* receive a security update — combined with confirmed exploitation and a public, weaponizable PoC makes the 7.8 label feel generous. We push this to 8.0 to reflect the real-world exposure, while acknowledging that the local-code-execution prerequisite is a genuine gate that keeps it from CRITICAL.

"KEV-listed Mali GPU LPE with public PoC on billions of Android devices demands immediate action."
02 · The Attack Path

6 steps from start to impact.

STEP 01

Initial code execution on-device

The attacker needs to run code locally on a device with a vulnerable Mali GPU driver. In the Variston-linked campaign, this was achieved via a Chrome type-confusion zero-day (CVE-2022-4262) delivered through a one-time SMS link. Alternatively, a malicious app installed from a sideloaded APK or a compromised third-party store works. Any in-app WebView rendering attacker-controlled content could also serve as the entry point.
Conditions required:
  • Target device runs a vulnerable Mali GPU kernel driver (Bifrost ≤r35p0, Midgard ≤r31p0, or Valhall ≤r35p0)
  • Attacker achieves local code execution via browser exploit, malicious app, or other app-level vector
Where this breaks in practice:
  • Requires a separate vulnerability or social-engineering step to get code running on the device
  • Modern Android sandboxing (seccomp, SELinux) restricts available syscalls from app context, though Mali ioctls are typically permitted
Detection/coverage: Google Play Protect may flag known malicious APKs; browser exploits require separate detection via Chrome CET/MTE or endpoint agents.
STEP 02

Open Mali GPU device and create imported memory region

The exploit opens /dev/mali0 (or the equivalent character device) and uses KBASE_IOCTL_MEM_IMPORT to create a KBASE_MEM_TYPE_IMPORTED_USER_BUF memory object. The attacker deliberately sets the KBASE_REG_CPU_WR flag *without* KBASE_REG_GPU_WR. Because the vulnerable code path only gates on the GPU write flag, this combination is accepted without raising an error.
Conditions required:
  • App has file-descriptor access to the Mali device node (standard on stock Android — not blocked by SELinux for apps using GPU)
  • Attacker controls the ioctl parameters
Where this breaks in practice:
  • Some hardened ROM builds (GrapheneOS) restrict direct GPU device access from untrusted contexts, but stock Android and Samsung OneUI do not
Detection/coverage: Unusual KBASE_IOCTL_MEM_IMPORT calls with atypical flag combinations could be detected by a kernel audit hook, but no mainstream EDR ships this rule.
STEP 03

Map target read-only file into the import buffer

The attacker mmaps a read-only file — the PoC uses /etc/passwd; a weaponized version targets a shared .so loaded by a privileged process — and feeds that mapping into the Mali imported-buffer region. The kernel pins the underlying physical pages via pin_user_pages_remote() with write=1 because of the missing KBASE_REG_CPU_WR check, even though the file VMA is read-only.
Conditions required:
  • Target file is readable by the app (e.g., world-readable shared libraries, /etc/passwd)
  • The Mali driver's page-pinning path calls pin_user_pages_remote with write=1
Where this breaks in practice:
  • If the target file is only readable by root (e.g. on hardened builds), this step fails — but most system libraries and /etc/passwd are world-readable on Android
STEP 04

Write to pinned pages via GPU job submission

The attacker submits a GPU compute or fragment job that writes attacker-controlled data to the pinned pages. Because the GPU was granted write access and the pages are now pinned as writable, the data lands in the page cache. The CPU-side read-only mapping is bypassed entirely — the write happens at the physical page level. STAR Labs demonstrated this by blanking root's password hash in the cached copy of /etc/passwd.
Conditions required:
  • Successful page pinning from Step 3
  • Ability to submit GPU jobs (normal app permission on Android)
Where this breaks in practice:
  • None — once pages are pinned writable, the GPU job completes reliably
Detection/coverage: Runtime integrity monitoring of /etc/passwd (e.g., AIDE, dm-verity for system partitions) could detect the modification, but dm-verity only covers the system partition, not /etc/passwd on /data.
STEP 05

Hijack privileged process or escalate to root

The modified page cache is shared across all processes mapping the same file. The PoC executes su root after blanking root's password. The STAR Labs weaponized chain goes further: it overwrites a shared library used by vold (Android's volume daemon running as root), triggering code execution in that context. From vold, the chain pivots through init → hal_neuralnetworks_armnn → loads a malicious kernel module (pktgen.ko) → disables SELinux → spawns a root reverse shell.
Conditions required:
  • Modified page cache is consumed by a privileged process before being evicted
  • SELinux not blocking the final payload execution (disabled in last stage of STAR Labs chain)
Where this breaks in practice:
  • dm-verity on A/B partition devices may prevent loading tampered system binaries on the read-only system partition — but the attack targets page cache of files on writable partitions or in-memory library mappings
  • Samsung KNOX Integrity Measurement Architecture (IMA) provides some defence, but it was bypassed in the documented Variston chain
Detection/coverage: Samsung KNOX Real-time Kernel Protection (RKP) may detect SELinux tampering; Google SafetyNet/Play Integrity attestation will flag a rooted device post-compromise.
STEP 06

Full device compromise and data exfiltration

With root and SELinux disabled, the attacker installs a persistent spyware suite. In the Variston-linked campaign, this was a C++ implant with modules for decrypting and capturing data from Signal, WhatsApp, Samsung Internet, Chrome, and other apps. The implant intercepts notifications, exfiltrates call logs, SMS, and location data, and can survive reboots through persistence mechanisms planted in system partitions.
Conditions required:
  • Root access achieved in Step 5
Where this breaks in practice:
  • Google Play Protect on-device scanning may detect known implant signatures
  • Device attestation (SafetyNet/Play Integrity) fails, potentially alerting MDM solutions
Detection/coverage: MDM/UEM agents monitoring device integrity (KNOX, Intune compliance) will detect the compromised state — but only if enrolled and configured to act on attestation failures.
03 · Compensating Control

1
HIGH 8.0→MEDIUM 5.5
SEVERITY REDUCED
Enforce minimum Android security patch level ≥2023-06-05 via MDM/UEM policy — The fix shipped in Android's June 2023 bulletin. Configure your MDM (Intune, Workspace ONE, KNOX, Jamf) to block corporate resource access (email, VPN, apps) for devices reporting a patch level older than 2023-06-05. This doesn't patch the device, but it quarantines the risk from your enterprise data. Per the noisgate mitigation SLA for HIGH, deploy this policy within 30 days. This is the single highest-leverage control for enterprises managing BYOD fleets.
2
HIGH 8.0→LOW 2.0
SEVERITY REDUCED
Retire or replace end-of-life Android devices that will never receive the patch — Devices with Mali GPUs from 2018–2021 that are no longer receiving OEM security updates are permanently vulnerable. Initiate a hardware refresh cycle for any device used for corporate access that cannot reach the 2023-06-05 patch level. Per the noisgate remediation SLA for HIGH, complete this within 180 days.
3
HIGH 8.0→HIGH 7.0
Enable Google Play Protect and restrict sideloading on managed devices — Play Protect scans for known exploit payloads and malicious apps. Disabling sideloading (Unknown Sources) eliminates the easiest local-code-execution path. Configure via managed Google Play or Samsung KNOX. This raises the cost of initial access needed before CVE-2022-22706 can be reached.
4
HIGH 8.0→MEDIUM 5.0
SEVERITY REDUCED
Deploy device attestation checks (SafetyNet / Play Integrity API) in enterprise apps — Enterprise apps and conditional-access policies should verify device integrity at runtime. A device compromised via this chain will fail SafetyNet/Play Integrity attestation (rooted, SELinux disabled). Configure your apps and identity provider to block access on attestation failure. This provides a post-exploitation detection and containment layer.
5
HIGH 8.0→HIGH 7.5
Block SMS-delivered links at the carrier or UEM level for high-risk users — The documented exploitation vector was a one-time SMS link. For executives, government officials, and other high-value targets, deploy SMS link filtering (Google Messages link preview blocking, or carrier-level URL filtering) and train users to never tap unexpected SMS URLs. This disrupts the exact delivery mechanism used in the Variston campaign.
What doesn't work
  • Network-level IDS/IPS — This is a local kernel exploit triggered via GPU ioctls on the device itself. No network traffic is generated during exploitation. Snort/Suricata/Zeek rules cannot detect it.
  • VPN or ZTNA alone — Encrypting or segmenting network traffic does not prevent a local privilege escalation on the endpoint. The attacker is already on the device.
  • Android app-level sandboxing — While Android's app sandbox restricts inter-app access, the Mali device node (/dev/mali0) is accessible from within the sandbox on stock Android. The entire point of this vuln is escaping the sandbox to root.
  • dm-verity — Protects the read-only system partition from modification, but the exploit targets page cache of files on writable partitions or in-memory library mappings. dm-verity does not cover /data, /etc, or runtime library caches.
04 · Intelligence Metadata

The supporting signals.

In-the-Wild StatusConfirmed exploited. Google TAG documented use in a December 2022 spyware campaign linked to Variston, targeting Samsung devices in the UAE via SMS-delivered exploit chains. CISA added to KEV on 2023-03-30 with remediation due 2023-04-20.
Exploit Chain ContextUsed as the kernel LPE stage in a four-bug chain: CVE-2022-4262 (Chrome type confusion, 0-day) → CVE-2022-3038 (Chrome sandbox escape, n-day) → CVE-2022-22706 (Mali LPE, n-day) → CVE-2023-0266 (ALSA sound subsystem, 0-day) + multiple kernel info-leak 0-days.
PoC AvailabilityPublic. byt3quester/CVE-2022-22706-poc on GitHub — a compilable C exploit that overwrites /etc/passwd page cache and sus to root. STAR Labs published a full exploit walkthrough in February 2025 with multi-stage LPE to root reverse shell.
EPSS0.01062 (~top 10% of scored CVEs). Low automated-exploitation probability reflects the local-access prerequisite, but EPSS systematically underweights mobile/embedded chains where initial access comes from a separate bug.
CVSS VectorCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H — 7.8 HIGH. Local vector, low complexity once on-device, low privilege required. The Scope:Unchanged is correct — the vuln stays within the kernel boundary even though the practical impact crosses process boundaries.
Affected VersionsMidgard r26p0–r31p0, Bifrost r0p0–r35p0, Valhall r19p0–r35p0. Essentially every Mali GPU driver shipped between ~2016 and January 2022. This covers Samsung Exynos, MediaTek Dimensity/Helio, HiSilicon Kirin, and other SoC families.
Fixed VersionsArm driver: Midgard r32p0, Bifrost/Valhall r36p0 (released January 2022). Android AOSP: patch level 2023-06-05. Samsung: May 2023 SMR. Google Pixel: June 2023. Many budget/mid-range Android devices from 2018-2021 will never receive this fix.
Installed BaseMali GPUs ship in ~40% of Android devices and >70% of smart TVs. Over 12 billion Arm GPUs shipped to date. The vulnerable driver range spans roughly 6 years of silicon.
Reporting ResearcherReported to Arm with indication of in-the-wild exploitation. Root cause analysis published by Google Project Zero (as CVE-2021-39793 duplicate analysis). Full exploitation research by STAR Labs SG (Billy Jheng Bing-Jhong, Muhammad Alifa Ramdhan).
Disclosure Timeline2022-01: Arm releases fix in r36p0/r32p0. 2022-03-03: CVE published. 2022-12: Exploited in Variston-linked campaign. 2023-03-30: CISA KEV listing. 2023-06: Android AOSP incorporates patch. 2025-02: STAR Labs full exploit writeup published.

Sources.

  1. Google TAG Blog – Spyware vendors use 0-days and n-days
  2. Google Project Zero – Root Cause Analysis (CVE-2021-39793 / CVE-2022-22706)
  3. STAR Labs – Mali-cious Intent: Exploiting GPU Vulnerabilities
  4. BleepingComputer – Android security update fixes Mali GPU bug exploited as zero-day
  5. Android Security Bulletin – June 2023
  6. NVD – CVE-2022-22706
  7. CVE Details – CVE-2022-22706
  8. byt3quester PoC – CVE-2022-22706-poc (via Sploitus)
05 · The Call

Final Verdict
= UNCHANGED to HIGH (8.0/10)

Why this verdict

  • Confirmed exploitation in sophisticated spyware campaign. Google TAG documented a Variston-linked operator using CVE-2022-22706 as the kernel-LPE stage in a four-bug chain delivered via SMS to Samsung devices in the UAE. This isn't theoretical — it was weaponized against real targets, and CISA added it to KEV in March 2023.
  • Public, compilable PoC eliminates the skill barrier. The byt3quester/CVE-2022-22706-poc GitHub repo is a self-contained C exploit that achieves root. STAR Labs' 2025 writeup provides a fully documented multi-stage escalation path. Any actor who can deliver code to a device can use this.
  • Massive, permanently unpatched installed base. Mali GPUs are in ~40% of Android devices — billions of handsets. The fix requires driver-level updates from OEMs. Budget and mid-range devices from 2018–2021 are overwhelmingly end-of-life and will never receive the June 2023 patch level. This creates a permanent population of exploitable devices.
  • Local-access gate is real but routinely chained. AV:L means you need code on the device first. On mobile, this is supplied by browser exploits (as in the documented chain), malicious apps, or compromised SDKs. The prerequisite is not a hard barrier for any actor operating above script-kiddie level — it's the normal cost of doing business in mobile exploitation.
  • Role multiplier: The canonical deployment role for Mali GPU drivers is *consumer and enterprise mobile devices*. In the low-value role (personal phone), compromise yields personal data — bad, but bounded. In the high-value role — executive/government/journalist phones — compromise yields corporate email, VPN credentials, MFA tokens, encrypted messaging plaintext, and real-time location. The documented Variston campaign specifically targeted this high-value role. However, this component is not canonically a fleet-management or identity-tier component (it's not a DC, hypervisor, or PKI system), so the blast radius is per-device rather than fleet-scale. This keeps the ceiling at HIGH rather than triggering the CRITICAL floor.

Why not higher?

CRITICAL would require either a network-facing attack vector (this is local-only) or a component whose compromise inherently cascades to fleet/domain/supply-chain scope. The Mali GPU driver runs on individual endpoints. Even full device compromise of one phone does not directly propagate to other devices or enterprise infrastructure without additional manual attacker effort. The local-access prerequisite means this bug is always the *second* step in a chain, never the initial entry point.

Why not lower?

The KEV listing and confirmed exploitation by a commercial spyware vendor immediately rule out anything below HIGH. The public PoC, the six-year window of affected driver versions, the billions of permanently unpatched devices, and the reliable root primitive make this one of the most impactful mobile LPE bugs disclosed in recent years. Downgrading to MEDIUM would require the attack to be unreliable or the population to be small — neither is true.

06 · Verification

Crowdsourced verification payload.

Run this script on the target Android device via adb shell or a terminal emulator app. It checks the Mali GPU driver version reported by the kernel. No root required. Example: adb shell 'bash -s' < check_mali_cve_2022_22706.sh

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/bin/bash
# check_mali_cve_2022_22706.sh
# Checks whether the Mali GPU kernel driver is vulnerable to CVE-2022-22706
# Run on the target Android/Linux device via: adb shell 'bash -s' < check_mali_cve_2022_22706.sh
# No root required. Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

VULNERABLE=1
PATCHED=0
UNKNOWN=2

# Try multiple known paths for Mali driver version
MALI_VERSION=""
for path in /sys/module/mali_kbase/version \
             /sys/module/mali/version \
             /sys/module/mali_kbase/parameters/mali_debug_level \
             /proc/driver/mali/version; do
    if [ -r "$path" ]; then
        MALI_VERSION=$(cat "$path" 2>/dev/null)
        break
    fi
done

# Fallback: check Android security patch level
SPL=$(getprop ro.build.version.security_patch 2>/dev/null)

if [ -z "$MALI_VERSION" ] && [ -z "$SPL" ]; then
    echo "UNKNOWN - Could not determine Mali driver version or Android patch level."
    echo "Device may not have a Mali GPU or paths are non-standard."
    exit $UNKNOWN
fi

# Check Android security patch level (fix shipped in 2023-06-05)
if [ -n "$SPL" ]; then
    # Compare dates: if SPL >= 2023-06-05, patched at OS level
    SPL_NUM=$(echo "$SPL" | tr -d '-')
    FIXED_NUM="20230605"
    if [ "$SPL_NUM" -ge "$FIXED_NUM" ] 2>/dev/null; then
        echo "PATCHED - Android security patch level $SPL >= 2023-06-05."
        echo "CVE-2022-22706 fix included in this patch level."
        exit $PATCHED
    fi
fi

# Parse Mali driver version string (e.g., "r36p0" or "r35p0")
if [ -n "$MALI_VERSION" ]; then
    # Extract rXXpY format
    DRIVER_VER=$(echo "$MALI_VERSION" | grep -oE 'r[0-9]+p[0-9]+')
    if [ -n "$DRIVER_VER" ]; then
        MAJOR=$(echo "$DRIVER_VER" | sed 's/r\([0-9]*\)p.*/\1/')
        MINOR=$(echo "$DRIVER_VER" | sed 's/r[0-9]*p\([0-9]*\)/\1/')
        # Bifrost/Valhall fixed in r36p0, Midgard fixed in r32p0
        # Conservative check: r36p0+ is safe for all architectures
        if [ "$MAJOR" -ge 36 ] 2>/dev/null; then
            echo "PATCHED - Mali driver version $DRIVER_VER >= r36p0."
            exit $PATCHED
        else
            echo "VULNERABLE - Mali driver version $DRIVER_VER is in the affected range."
            echo "CVE-2022-22706 affects Midgard r26p0-r31p0, Bifrost r0p0-r35p0, Valhall r19p0-r35p0."
            echo "Fixed in Bifrost/Valhall r36p0, Midgard r32p0."
            exit $VULNERABLE
        fi
    fi
fi

# If we only have SPL and it's old
if [ -n "$SPL" ]; then
    echo "VULNERABLE - Android security patch level $SPL is older than 2023-06-05."
    echo "Device likely lacks the CVE-2022-22706 fix. Verify Mali driver version manually."
    exit $VULNERABLE
fi

echo "UNKNOWN - Could not parse Mali driver version from: $MALI_VERSION"
exit $UNKNOWN