
CVE-2026-43499: Linux kernel futex PI use-after-free research package
remove_waiter() in kernel/locking/rtmutex.c wird von den Slowlock-Pfaden verwendet, aber auch für das Proxy-Lock-Rollback in rt_mutex_start_proxy_lock(), wenn es von futex_requeue() aufgerufen wird.
Im Proxy-Lock-Fall ist waiter::task nicht current, aber remove_waiter() arbeitet fälschlicherweise mit current. Dies verursacht drei Probleme:
waiter::task::pi_lock gehalten wird.pi_blocked_on der Wartetask wird nicht gelöscht, sodass ein hängender Zeiger zurückbleibt, der für einen Use-After-Free vorbereitet ist.rt_mutex_adjust_prio_chain() arbeitet auf der falschen Task.CWE-416 (Use After Free). CVSS 3.1: 7.8 HIGH (Lokal, Geringe Komplexität, Geringe Rechte erforderlich).
Betroffen: Linux 2.6.39 bis 6.18.x; gepatcht in 6.1.175, 6.6.140, 6.12.86, 6.18.27, 7.0.4.
Nicht eskalierende Validierungs-Harness nur für das autorisierte Testgerät.
Reproduzierbares Paket: test_package/ (Build, Hashes, ADB-Schritte, Offenlegung).
Voraussetzungen: Android NDK r27+, adb. Unter Windows: .\build.ps1.
.\build.ps1
adb push build/ghostlock_validate /data/local/tmp/ghostlock_validate
adb shell chmod 755 /data/local/tmp/ghostlock_validate
# Safe default (recommended)
adb shell /data/local/tmp/ghostlock_validate --dry-run --retries 3
# Optional crash probe (may panic) — not for privilege escalation
# adb shell /data/local/tmp/ghostlock_validate --probe --retries 1
--dry-run erfolgreich: EDEADLK=1 + DRY_RUN_STOP_BEFORE_CORRUPTION=1.
Nachweispaket (was auf diesem Telefon demonstriert wird / nicht demonstriert wird): evidence/PROOF.md
Anbieterpaket (Dry-Run-Transkripte + Offenlegungspaket): evidence/vendor_package_20260726/
Anbieter-Offenlegung: test_package/docs/VENDOR_DISCLOSURE.md.
Öffentliche Repos für andere Geräte (nur als Referenz, nicht auf amber anwendbar): evidence/OTHER_DEVICE_REPOS.md
Es sind keine Credential-/SELinux-/CFI-/Root-Stufen implementiert.
Gemeldet von:
Fix verfasst von: Keenan Dong
Commit durchgeführt von: Thomas Gleixner
Commit: 3bfdc63 — rtmutex: Use waiter::task instead of current in remove_waiter()