This is a bad gearbox inside a race car, not a landmine in the parking lot
CVE-2026-0028 is an integer-overflow bug in Android's pKVM hypervisor memory-protection path, specifically __pkvm_host_share_guest in mem_protect.c, that can turn a size calculation into an out-of-bounds write. Google shipped the fix in the March 2026 Android bulletin, and the patch was backported across three Android common-kernel branches; practically, the affected population is ARM64 devices that actually ship and use pKVM/AVF and were still below the 2026-03-05 security patch level. Based on AOSP docs, pKVM is part of the Android virtualization stack on ARM64 and appears in GKI lines including android-13-5.x, with newer docs also covering android15-6.6 and android16-6.12 branch families.
Google labeled the issue Critical in the kernel-components table, but that overstates fleet risk for enterprise defenders. The blast radius on a single compromised device is ugly because this sits near the hypervisor trust boundary, yet the attack path is still local, requires code execution on the handset first, and only matters on the subset of devices where pKVM is present and reachable in real use; add no KEV, no public exploit evidence I could verify, and an EPSS of 0.00007, and this lands at ASSESSED AT HIGH, not CRITICAL.
4 steps from start to impact.
Land code execution on the handset
- Local execution as an unprivileged app, shell user, or equivalent handset foothold
- Target device is Android and unpatched below security patch level
2026-03-05
- Managed Play-only deployments, MDM app allowlisting, and Play Protect reduce malicious app delivery
- No direct network entry point; attacker must already be on the device
Reach the pKVM memory-sharing path
- ARM64 device with pKVM support present
- A reachable code path that invokes the mem_protect HVC flow
- pKVM is not universal across the Android fleet
- Many enterprise phones do not actively use protected VMs in normal business workflows
Trigger integer overflow into EL2 memory corruption
addr + size can wrap, causing range validation to lie and enabling an out-of-bounds write. Google's patch adds check_add_overflow() guards before page-state range checks, which is a strong signal that the exploitable condition is malformed size arithmetic rather than a subtle race.- Attacker can supply crafted address/size values into the vulnerable sharing path
- Kernel branch lacks the September 2025 backport commit
- Reliable exploitation against hypervisor-adjacent code is harder than crashing it
- Different SoCs, branch backports, and memory layouts can make weaponization brittle
Escalate privilege and break the trust boundary
- Successful, stable memory corruption primitive
- Target uses pKVM-backed isolation for sensitive workloads
- No public exploit I could verify, so operational reliability is unproven
- On devices that never use protected VMs, the practical defender impact is narrower
2026-03-05, with unknown app-source enabled, developer options active, or weak device integrity posture. That gives you a practical risk stack for triage while the actual patch propagates, and should be folded into your mobile hardening checks within 30 days.- Perimeter IPS/WAF controls do not help because this is not a network-reachable vulnerability.
- Server-side vulnerability scanners will not tell you who is exposed; they do not meaningfully inspect local Android kernel patch state or pKVM reachability.
- Containerizing enterprise apps does not fix a vulnerable kernel/hypervisor path once the attacker already has device-level code execution.
The supporting signals.
| In-the-wild status | No confirmed active exploitation found. I found no CISA KEV entry and no vendor statement claiming in-the-wild use; treat this as *currently unconfirmed*, not safe. |
|---|---|
| Proof-of-concept availability | No public PoC I could verify in GitHub/Exploit-DB-style searches. What is public today is the patch diff, which materially lowers exploit-development cost for a skilled Android kernel researcher. |
| EPSS | 0.00007 from the user-supplied intel block, which is extremely low and matches the narrow, local-only reachability. |
| KEV status | Not KEV-listed as of 2026-05-29 review date; no federal active-exploitation signal. |
| CVSS context | No vendor CVSS score published. NVD shows no NVD CVSS, though CISA ADP later attached CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H as enrichment. I did not use that as a vendor baseline because the CNA/vendor bulletin did not publish a score. |
| Affected surface | Android ARM64 pKVM/AVF path only. AOSP says AVF/pKVM is limited to ARM64, with pKVM included in android-13-5.x GKI and later branch families used by Android virtualization. |
| Fixed versions | Patched by Android security patch level 2026-03-05 or later. The fix appears as backports in three ACK commits: 986614312222d4b3bdcf16840cdb4abdaed8a42d, aff2255dbe38dc7c57bac8d3ba9feed989289b20, and f3a4b4d4a1fe2aface7de74ac257b8705b6de472. |
| Scanning / exposure data | External scanner data is basically irrelevant here. This is a local kernel/hypervisor flaw on handsets, not an internet-facing daemon; Shodan/Censys/GreyNoise-style exposure counts do not meaningfully describe reachable population. |
| Disclosure date | 2026-03-02 publication in NVD/CNA flow, with fixes carried in the March 2026 Android bulletin. |
| Research / attribution | Patch authored by Vincent Donnefort (Google) in the public ACK backports. I found no public researcher write-up or credited external finder tied to this specific CVE. |
Sources.
- NVD entry for CVE-2026-0028
- Android Security Bulletin — March 2026
- ACK patch backport commit 986614312222d4b3bdcf16840cdb4abdaed8a42d
- ACK patch backport commit aff2255dbe38dc7c57bac8d3ba9feed989289b20
- ACK patch backport commit f3a4b4d4a1fe2aface7de74ac257b8705b6de472
- Android AVF architecture
- Try Android Virtualization Framework (AVF)
- CISA Known Exploited Vulnerabilities Catalog
Why this verdict
- Post-initial-access only: the attacker already needs code execution on the handset, which is immediate downward pressure from any hypothetical critical baseline.
- Reachable population is narrower than 'all Android': this is a pKVM/AVF path on ARM64 devices, not a generic framework bug reachable on every managed phone.
- Impact is still serious where present: the bug targets hypervisor-adjacent memory protection, so a win here can cross a stronger isolation boundary than an ordinary userspace LPE.
Why not higher?
I am not calling this CRITICAL because there is no remote path, no KEV, and no public exploit evidence I could verify. The combination of local foothold requirement plus pKVM-specific reachability means the exposed population is materially smaller than the Android bulletin's worst-case severity language suggests.
Why not lower?
I am not pushing this to MEDIUM because the vulnerable code is not low-value plumbing; it lives in pKVM memory protection, close to the trust boundary for protected VMs. If your fleet includes modern Pixel-class or premium ARM64 devices using AVF features, a successful exploit would be a meaningful device-compromise amplifier.
Crowdsourced verification payload.
Run this from an auditor workstation with adb installed against a connected or remotely-debuggable Android device: ./check-cve-2026-0028.sh SERIAL1234. It needs no root for the basic patch-level verdict; if the device blocks some filesystem probes, the script will fall back to UNKNOWN rather than guessing.
#!/usr/bin/env bash
# check-cve-2026-0028.sh
# Determine likely exposure to CVE-2026-0028 on an Android device via adb.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN, 3=usage/adb failure
set -euo pipefail
if [[ $# -ne 1 ]]; then
echo "Usage: $0 <adb-serial>"
exit 3
fi
SERIAL="$1"
ADB=(adb -s "$SERIAL")
if ! command -v adb >/dev/null 2>&1; then
echo "UNKNOWN"
echo "Reason: adb not installed"
exit 2
fi
if ! "${ADB[@]}" get-state >/dev/null 2>&1; then
echo "UNKNOWN"
echo "Reason: device not reachable via adb"
exit 2
fi
getprop_safe() {
"${ADB[@]}" shell getprop "$1" 2>/dev/null | tr -d '\r'
}
shell_safe() {
"${ADB[@]}" shell "$1" 2>/dev/null | tr -d '\r'
}
PATCH_LEVEL="$(getprop_safe ro.build.version.security_patch)"
ABI_LIST="$(getprop_safe ro.product.cpu.abilist64)"
ARCH="$(shell_safe 'uname -m')"
SDK="$(getprop_safe ro.build.version.sdk)"
MODEL="$(getprop_safe ro.product.model)"
VIRT_APEX="$(shell_safe 'pm path com.android.virt >/dev/null 2>&1; echo $?')"
HYP_TRACE="$(shell_safe 'if [ -d /sys/kernel/tracing/hypervisor ] || [ -d /sys/kernel/debug/tracing/hypervisor ]; then echo yes; else echo no; fi')"
KVM_DEV="$(shell_safe 'if [ -e /dev/kvm ]; then echo yes; else echo no; fi')"
# Compare dates lexicographically because Android patch levels are YYYY-MM-DD.
FIXED_DATE="2026-03-05"
is_arm64=no
if [[ "$ARCH" == "aarch64" ]] || [[ "$ABI_LIST" == *"arm64"* ]]; then
is_arm64=yes
fi
pkvm_signal=no
if [[ "$VIRT_APEX" == "0" ]] || [[ "$HYP_TRACE" == "yes" ]] || [[ "$KVM_DEV" == "yes" ]]; then
pkvm_signal=yes
fi
echo "Model: ${MODEL:-unknown}"
echo "SDK: ${SDK:-unknown}"
echo "Arch: ${ARCH:-unknown}"
echo "Patch level: ${PATCH_LEVEL:-unknown}"
echo "AVF APEX present: ${VIRT_APEX:-unknown} (0 means present)"
echo "Hypervisor tracefs present: ${HYP_TRACE:-unknown}"
echo "/dev/kvm present: ${KVM_DEV:-unknown}"
if [[ -z "$PATCH_LEVEL" ]]; then
echo "UNKNOWN"
echo "Reason: unable to read security patch level"
exit 2
fi
if [[ "$PATCH_LEVEL" > "$FIXED_DATE" || "$PATCH_LEVEL" == "$FIXED_DATE" ]]; then
echo "PATCHED"
echo "Reason: device patch level is ${PATCH_LEVEL}, which is >= ${FIXED_DATE}"
exit 0
fi
if [[ "$is_arm64" != "yes" ]]; then
echo "PATCHED"
echo "Reason: device is not ARM64; pKVM/AVF protected mode is ARM64-focused and this CVE is not expected to apply"
exit 0
fi
if [[ "$pkvm_signal" == "yes" ]]; then
echo "VULNERABLE"
echo "Reason: ARM64 device below ${FIXED_DATE} with virtualization/pKVM indicators present"
exit 1
fi
echo "UNKNOWN"
echo "Reason: device is below ${FIXED_DATE}, but pKVM/AVF presence could not be confirmed without deeper OEM-specific inspection"
exit 2