CVE-2026-91007: Arbitrary supervisor-mode function pointer injection via charger_set_prop() syscall in the charger driver API
The user-mode syscall verifiers for the charger driver API in drivers/charger/chargerhandlers.c did not inspect the prop argument before copying union chargerpropval across the user/kernel boundary. Two members of that union are function pointers — statusnotification (CHARGERPROPSTATUSNOTIFICATION) and onlinenotification (CHARGERPROPONLINENOTIFICATION), declared in include/zephyr/drivers/charger.h — and zvrfychargersetprop() forwarded the caller-supplied union verbatim to the driver's setproperty callback for any property. zvrfychargergetprop() had the mirror defect and copied the stored kernel callback address back out to user memory.
With CONFIGUSERSPACE enabled, any user-mode thread that has been granted a charger device object could call chargersetprop() with CHARGERPROPSTATUSNOTIFICATION or CHARGERPROPONLINENOTIFICATION and an arbitrary pointer value. Drivers that implement these properties — drivers/charger/chargermax20335.c, drivers/charger/chargerpf1550.c and drivers/charger/chargerbq2518x.c — store the pointer in device data and later invoke it from their interrupt work handlers, which run in supervisor mode, on any charger state change such as a cable plug/unplug.
The result is a control-flow hijack at kernel privilege from an unprivileged thread, defeating the isolation that CONFIGUSERSPACE is meant to provide; the read path additionally disclosed a kernel code address to user mode, and clearing a notifier installed by a supervisor thread let user mode suppress charger notifications. Supervisor-mode callers of chargersetprop()/chargergetprop() are unaffected.
The fix makes both verifiers reject the two notifier properties outright — including when the supplied callback is NULL, since the notifiers are device state — and adds a BUILDASSERT on CHARGERPROPCOMMONCOUNT so that new properties force a re-review of the union's user-mode safety.
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Compensating control
Update the user-mode charger syscall verifiers in drivers/charger/charger_handlers.c to reject CHARGER_PROP_STATUS_NOTIFICATION and CHARGER_PROP_ONLINE_NOTIFICATION outright, including when the callback is NULL, before copying the charger_propval union across the user/kernel boundary; add a BUILD_ASSERT on CHARGER_PROP_COMMON_COUNT so new properties trigger a user-mode safety review.
Event History
Frequently Asked Questions
Which systems are exposed to this issue?
The issue requires CONFIG_USERSPACE to be enabled and a user-mode thread to have been granted access to a charger device object. It affects the MAX20335, PF1550, and BQ2518x charger drivers when they implement the affected notification properties.
What does an attacker need to exploit it?
An attacker needs execution as a user-mode thread with access to a charger device object. They can set either CHARGER_PROP_STATUS_NOTIFICATION or CHARGER_PROP_ONLINE_NOTIFICATION to an arbitrary pointer through charger_set_prop().
When is the supplied pointer executed?
The affected drivers store the supplied notification pointer and invoke it from interrupt work handlers running in supervisor mode. A charger state change triggers that later invocation.
Can this issue disclose kernel addresses as well as enable code execution?
Yes. The mirrored charger_get_prop() verifier defect can copy a stored kernel callback address back to user memory for the affected notification properties.
What can be done before patching?
Prevent user-mode threads from receiving charger device object access, since that access is required for exploitation. Systems that do not enable CONFIG_USERSPACE are not exposed through the described syscall path.