The user-mode syscall verifiers for the charger driver API in drivers/charger/charger_handlers.c did not inspect the prop argument before copying union charger_propval across the user/kernel boundary. Two members of that union are function pointers — status_notification (CHARGER_PROP_STATUS_NOTIFICATION) and online_notification (CHARGER_PROP_ONLINE_NOTIFICATION), declared in include/zephyr/drivers/charger.h — and z_vrfy_charger_set_prop() forwarded the caller-supplied union verbatim to the driver's set_property callback for any property. z_vrfy_charger_get_prop() had the mirror defect and copied the stored kernel callback address back out to user memory.
With CONFIG_USERSPACE enabled, any user-mode thread that has been granted a charger device object could call charger_set_prop() with CHARGER_PROP_STATUS_NOTIFICATION or CHARGER_PROP_ONLINE_NOTIFICATION and an arbitrary pointer value. Drivers that implement these properties — drivers/charger/charger_max20335.c, drivers/charger/charger_pf1550.c and drivers/charger/charger_bq2518x.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 CONFIG_USERSPACE 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 charger_set_prop()/charger_get_prop() 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 BUILD_ASSERT on CHARGER_PROP_COMMON_COUNT so that new properties force a re-review of the union's user-mode safety.
{
"cna_assigner": "zephyr",
"cwe_ids": [
"CWE-822"
],
"osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/91xxx/CVE-2026-91007.json"
}{
"extracted_events": [
{
"range": [
{
"introduced": "3.7.0"
},
{
"fixed": "4.3.2"
}
],
"source": "AFFECTED_FIELD",
"strategy": "StandardRange"
},
{
"range": [
{
"introduced": "4.4.0"
},
{
"fixed": "4.5.0"
}
],
"source": "AFFECTED_FIELD",
"strategy": "StandardRange"
},
{
"range": [
{
"fixed": "5467b7a73fe093d7e9562ee15c321cf8f1639d17"
}
],
"source": "REFERENCES_COMMIT"
}
]
}
"https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-91007.json"
[
{
"deprecated": false,
"digest": {
"function_hash": "135671728715956968614881763111089236470",
"length": 264
},
"id": "CVE-2026-91007-27d31c24",
"signature_type": "Function",
"signature_version": "v1",
"source": "https://github.com/zephyrproject-rtos/zephyr/commit/5467b7a73fe093d7e9562ee15c321cf8f1639d17",
"target": {
"file": "drivers/charger/charger_handlers.c",
"function": "z_vrfy_charger_set_prop"
}
},
{
"deprecated": false,
"digest": {
"line_hashes": [
"114860826525212272255387724671090419464",
"18156603640688051097830428958672999140",
"189337282193128807407184708172801373493",
"338212482323067244305512741023087977285",
"291640840378158165891585621485994520487",
"203644163434794541418189084362876841964",
"316881235010947820751640611313203982145",
"44909499680743825748063703036544397163"
],
"threshold": 0.9
},
"id": "CVE-2026-91007-3cf851e0",
"signature_type": "Line",
"signature_version": "v1",
"source": "https://github.com/zephyrproject-rtos/zephyr/commit/5467b7a73fe093d7e9562ee15c321cf8f1639d17",
"target": {
"file": "drivers/charger/charger_handlers.c"
}
},
{
"deprecated": false,
"digest": {
"function_hash": "138357392328452215464426634333830398141",
"length": 296
},
"id": "CVE-2026-91007-da3a35a4",
"signature_type": "Function",
"signature_version": "v1",
"source": "https://github.com/zephyrproject-rtos/zephyr/commit/5467b7a73fe093d7e9562ee15c321cf8f1639d17",
"target": {
"file": "drivers/charger/charger_handlers.c",
"function": "z_vrfy_charger_get_prop"
}
}
]
"2026-11-13T07:08:39Z"