CVE-2026-89468
NoneCVSS
—
EPSS
0.2%
Published
Sep 11, 2026
CISA due date
—
Cloudanix analysis
A bug in the software that talks to a specific battery-charger chip can crash some devices, and in uncommon cases could let someone who already has access take more control when that charger is disconnected.
- Exploitation
- Local Privilege
- Attacker needs
- Local User
- Complexity
- High
- Impact
- Privilege Gain
- Component
- OS kernel
- Class
- Use After Free
- Remediation
- Patch
- Effort
- Low
- Patch risk
- Low
What it actually does
A race in the Linux kernel lp8788-charger power-supply driver can free charger private data (pchg) while a work item still runs. lp8788_charger_remove() flushed charger_work before unregistering IRQs, so a threaded IRQ handler could re-queue work after flush_work() returned; that work then ran after devres freed pchg and dereferenced it in lp8788_charger_event(). The result is a kernel use-after-free: typically an oops/panic, and in principle a local memory-corruption primitive if the race and freed object can be controlled.
Why it matters to the business
Impact is limited to Linux systems that actually use the Texas Instruments LP8788 charger/PMIC and load this driver—mostly specialized embedded, industrial, or mobile hardware, not typical servers or cloud guests. EPSS is very low (~0.17%) and unchanged over 30 days, the issue is not in CISA KEV, ransomware use is not reported, and exploit maturity is none about a month after publication. Realistic outcomes are device crash or reboot during charger unbind/remove; privilege escalation is theoretical and constrained by rare hardware and a local race. Treat as a normal kernel hygiene patch, not an emergency, unless LP8788 platforms with untrusted local users are in production.
How an attack unfolds
An attacker needs local access on a machine where lp8788-charger is bound to LP8788 hardware. They induce driver teardown (unbind, module unload, or equivalent device removal) while charger IRQs can still fire. Because IRQs were torn down after the workqueue flush, a threaded handler can queue charger_work after flush_work() returns; when the work later runs, lp8788_charger_event() uses the already-freed pchg. Winning that race can crash the kernel; converting it to reliable code execution would require additional heap control and is not known to be weaponized. The bug was found by static analysis. No named APT groups, campaigns, public exploits, or ransomware use are associated with it.
How to fix it
Apply the upstream kernel change that unregisters IRQs first (free_irq() waits for running threaded handlers so they cannot queue more work) and then uses cancel_work_sync() on charger_work in lp8788_charger_remove(). Install a distribution or vendor kernel that contains that fix, or backport the commit into OEM/Android/Yocto trees. No exact package versions were published with this record—track distro kernel advisories and changelogs for lp8788-charger. If the LP8788 charger is unused, blacklist or do not load the lp8788_charger module so the remove path cannot run. There is no sysctl or config flag that closes the race while the driver remains bound and removable.
How to confirm the fix worked
Confirm lp8788_charger_remove() unregisters IRQs before cancel_work_sync() on charger_work (kernel source, distro changelog, or git history of the driver). Verify the running kernel package includes that commit. Exposure: module lp8788_charger loaded, power_supply sysfs for LP8788, or device-tree/board files describing that PMIC. Systems without LP8788 hardware are not affected. After patching, a controlled unbind/reload of the driver on lab hardware should not produce UAF oopses or KASAN reports in lp8788_charger_event().
Typical attack path
- Obtain local access on a Linux system that loads the lp8788-charger driver against LP8788 hardware
- Ensure the charger device is bound and IRQs or charger_work can still run
- Trigger driver removal (unbind, module unload, or device teardown) concurrently with IRQ activity
- Win the race so charger_work executes after pchg is freed
- Cause a kernel oops via the use-after-free in lp8788_charger_event(), or attempt to turn the UAF into local privilege escalation with further heap manipulation
- If elevated kernel context is obtained, persist or expand access on that host
How to detect it
No public exploitation is known; hunt for crash evidence rather than C2. Review kernel logs and dumps around charger unbind, module unload, or device removal: dmesg, journalctl -k, /var/log/kern.log, kdump/vmcore, pstore, serial console. Look for oops/panic, KASAN use-after-free, or paging/NULL-deref reports whose call traces include lp8788_charger_event, lp8788_charger_remove, or the lp8788-charger driver, especially after flush/cancel of charger_work. Correlate with rmmod/unbind of lp8788_charger. Hosts without LP8788 hardware or the module are extremely unlikely to have been targeted.
- lp8788_charger_event
- lp8788_charger_remove
- lp8788_charger
- lp8788-charger
- KASAN: use-after-free
- Unable to handle kernel paging request
- BUG: kernel NULL pointer dereference
- Call Trace:
What your security team should do
- Inventory Linux endpoints for the lp8788_charger module or LP8788 PMIC; skip generic servers and cloud images unless custom kernels are in use
- Patch via normal kernel update/backport cadence—this is not KEV-driven and EPSS is negligible
- Where the charger is unused, blacklist lp8788_charger to remove the code path
- Watch vendor/distro kernel notes for the IRQ-unregister plus cancel_work_sync fix
- Do not prioritize over KEV or high-EPSS kernel issues; no in-the-wild exploitation is indicated
The record
In the Linux kernel, the following vulnerability has been resolved: power: supply: lp8788-charger: fix use-after-free on remove lp8788_charger_remove() flushes charger_work before unregistering the IRQs. An IRQ thread can queue charger_work after flush_work() has returned. The work can then run after devres frees pchg and dereference it in lp8788_charger_event(). Unregister the IRQs first. free_irq() waits for any running threaded handler, so no handler can queue more work afterwards. Then use cancel_work_sync() to cancel pending work or wait for running work to finish. This issue was found by an in-house static analysis tool.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|