CVE-2026-70640 is a race condition in the Android JNI bindings for llama.cpp. The vulnerability manifests as a use-after-free between concurrent calls to bench_1model() and free_1context(), triggered when these auto-generated JNI stubs are invoked from different threads — a scenario the llama.cpp API explicitly does not prohibit but the binding never guards against. The UAF enables a vtable hijack in llama_batch_allocr::clear() at offset +0x30, providing a reliable exploitation primitive that compensates for Android's ASLR weaknesses.
The CVSS 7.0 rating likely understates the severity in production inference deployments. While heap spraying is listed as a prerequisite, the supply-chain vector through model loading collapses this concern entirely: an attacker can prime heap state by supplying a malicious model file (crafting quantized metadata, GGUF schema fields, or safetensors structures) rather than requiring a separate spray payload. If your Android application loads models from untrusted sources — enterprise model registries, HuggingFace mirrors, user-supplied files — treat this as a direct RCE pathway.
The deeper problem is deployment permanence. llama.cpp lacks a stable release track, and most mobile applications embed it as a statically-linked blob compiled into the APK. The CVE's build range (b1886–b7445) assumes patch propagation, but for existing apps, 'patched' may never arrive — the vulnerable code persists until the application is rebuilt and redistributed. This is not a 'update to the latest version' vulnerability; it's a 'identify your build hash and rebuild if a fix exists at all' vulnerability.
Triage steps: First, verify whether your application links llama.cpp statically by inspecting the compiled native library for the bench_1model and free_1context symbols. Second, audit model loading paths — any code path that accepts models from untrusted input and feeds them through the JNI binding is a trigger surface. Third, enforce model provenance verification: cryptographically signed models from trusted registries eliminate the heap-priming vector. Fourth, if rebuild is feasible, update to a commit after b7445 and validate that concurrent bench/free calls no longer cause the race — the fix requires synchronizing the JNI entry points or adding explicit thread-safety markers to the binding layer.