CVE-2026-72111
The CVE-2026-72111 fix addresses more than an isolated code path error — it exposes a structural soundness flaw in how the BPF verifier propagates register state across instructions. Understanding why requires looking at what the patch actually does: it adds a mark_reg_unknown() call before performing a narrowing operation (__mark_reg_s32_range()) on the is_retval path in check_mem_access(). The else branch already contained this pattern, establishing the correct precedent that was apparently missed when the is_retval path was added. The core problem is that BPF verifier state can carry stale bounds forward across instructions. When a BPF_MOV64_IMM to zero establishes tight bounds and a subsequent LSM hook return value load intersects those bounds with the hook's valid range, the verifier believes it knows the exact register value when the actual loaded value differs. This is abstract interpretation diverging from concrete runtime behavior — the verifier's safety guarantees become unreliable because they rest on incorrect state assumptions. What makes this analytically significant is the pattern itself. The fix (adding mark_reg_unknown() before narrowing) has appeared before in verifier history, applied to different code paths as each instance was discovered. This recurring pattern points to two underlying failures. First, an API ergonomics problem: __mark_reg_s32_range() has an implicit precondition — clean register state — that its signature and documentation never express. It silently intersects bounds on any register, making it a trap for developers adding new paths. Second, an institutional knowledge problem: the correct pattern exists in the else branch as tacit knowledge rather than being enforced at the type or API level. Developers following the specification of what the code should do, rather than consulting the abstract interpretation model, naturally produce unsound implementations. The blast radius of this class of vulnerability matters more than any single instance's exploitability. Abstract interpretation unsoundness in the BPF verifier doesn't stay contained — it propagates through every safety decision the verifier makes thereafter. The is_retval path is structurally a minority branch that atrophied between audits, and BPF's expanding LSM hook usage has increased its runtime reach even as maintenance attention stayed flat. The gap between what maintainers assume about a code path's exposure and its actual reachability widens over time. For defenders: prioritize applying this fix immediately, but recognize it as a data point in a recurring class. The real question is how many other narrowing operations in the verifier assume clean register state without enforcing it. Audit existing call sites of __mark_reg_s32_range() for exactly this pattern — missing mark_reg_unknown() calls before narrowing — and treat each instance as a potential soundness violation, not just a local bug. The long-term fix isn't patching individual paths; it's redesigning the narrowing API so that state reset is mandatory rather than optional, or implementing static analysis that catches these violations at code review time.
Reviewed through automated stages and approved by a human before publication.