{"id":"CVE-2026-91007","kind":"vulnerability","aliases":["CVE-2026-91007"],"related":[],"title":"Zephyr: charger driver lets user threads hijack kernel control flow","description":"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.\n\nWith 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.\n\nThe 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.\n\nThe 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.","summary":"Zephyr's charger driver API does not check two function-pointer properties when user-mode threads pass them in, so an unprivileged thread can store an arbitrary pointer that the kernel later calls. The read path also leaks a kernel code address to user mode, and a user thread can clear notifiers set by supervisor code.","severity":"high","cvss":7.8,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["bq2518x","charger-drivers","embedded","infrastructure","max20335","pf1550","zephyr"],"not_affected_if":["default-config","no-charger-driver","supervisor-only-callers"],"how_to_check":"- Check whether `CONFIG_USERSPACE` is enabled in the Zephyr build configuration (`prj.conf` or the board Kconfig).\n- Check whether the firmware uses the `max20335`, `pf1550` or `bq2518x` charger drivers.\n- Check whether any user-mode thread is granted a charger device object.","fix":"- Apply the upstream patch linked in the sources; the sources do not name a fixed Zephyr release version.","status":"open","published_at":"2026-11-12T16:19:21+00:00","first_seen_at":"2026-11-12T16:44:02+00:00","triaged_at":"2026-11-12T16:45:43+00:00","updated_at":"2026-11-12T16:45:43+00:00","category":"infrastructure","confidence":0.8,"triage":{"at":"2026-11-12T16:45:43Z","model":"claude-haiku-5-5","output":{"fix":"- Apply the upstream patch linked in the sources; the sources do not name a fixed Zephyr release version.","reach":"local","title":"Zephyr: charger driver lets user threads hijack kernel control flow","impact":"high","summary":"Zephyr's charger driver API does not check two function-pointer properties when user-mode threads pass them in, so an unprivileged thread can store an arbitrary pointer that the kernel later calls. The read path also leaks a kernel code address to user mode, and a user thread can clear notifiers set by supervisor code.","audience":"businesses","category":"infrastructure","nicknames":[],"who_cares":["zephyr","embedded","charger-drivers","max20335","pf1550","bq2518x"],"confidence":0.8,"fix_status":"available","needs_auth":"yes","worst_case":"Unprivileged thread gains kernel-level code execution through a charger callback.","analyst_note":"Find the fixed Zephyr release version in the linked patch or vendor advisory.","how_to_check":"- Check whether `CONFIG_USERSPACE` is enabled in the Zephyr build configuration (`prj.conf` or the board Kconfig).\n- Check whether the firmware uses the `max20335`, `pf1550` or `bq2518x` charger drivers.\n- Check whether any user-mode thread is granted a charger device object.","plain_action":"","product_name":"","needs_analyst":true,"not_affected_if":["default-config","supervisor-only-callers","no-charger-driver"],"who_is_affected":"Only firmware built on Zephyr with CONFIG_USERSPACE enabled, where user-mode threads are granted access to a charger device, is exposed. Firmware with CONFIG_USERSPACE disabled, or where only supervisor-mode code calls the charger API, is not affected, and boards without the three listed charger drivers are outside the affected code paths.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"high"},"cost_usd":0.001417,"input_tokens":5192,"output_tokens":1795,"severity_before":"high"},"analyst_status":null,"analyst_note":null,"search":"'-2026':12A,15A '-91007':13A,16A '/charger_get_prop':316C 'across':108C 'add':344C 'addit':284C 'address':69B,174C,289C 'also':64B 'api':30B,94C 'arbitrari':54B,214C 'argument':102C 'assert':347C 'back':175C 'boundari':111C 'bq2518x':17B 'build':346C 'cabl':254C 'call':60B,198C 'callback':155C,173C,334C 'caller':145C,311C 'caller-suppli':144C 'chang':250C 'charger':2A,19B,28B,92C,106C,122C,129C,139C,161C,194C,199C,203C,208C,248C,306C,313C,349C 'charger-driv':18B 'check':33B 'clear':78B,294C 'code':68B,83B,288C 'common':351C 'config':181C,275C 'control':9A,261C 'control-flow':260C 'copi':104C,169C 'could':197C 'count':352C 'cve':11A,14A 'data':231C 'declar':133C 'defeat':271C 'defect':167C 'devic':195C,230C,341C 'disclos':285C 'driver':3A,20B,29B,93C,151C,217C 'drivers/charger/charger_bq2518x.c':225C 'drivers/charger/charger_handlers.c':96C 'drivers/charger/charger_max20335.c':222C 'drivers/charger/charger_pf1550.c':223C 'embed':21B 'enabl':183C 'fix':320C 'flow':10A,262C 'forc':357C 'forward':142C 'function':36B,118C 'function-point':35B 'get':162C 'grant':192C 'handler':240C 'hijack':7A,263C 'implement':219C 'includ':330C 'include/zephyr/drivers/charger.h':135C 'infrastructur':22B 'inspect':99C 'instal':297C 'interrupt':238C 'invok':234C 'isol':273C 'kernel':8A,58B,67B,172C,265C,287C 'later':59B,233C 'leak':65B 'let':4A,302C 'make':321C 'max20335':23B 'meant':278C 'member':113C 'memori':179C 'mirror':166C 'mode':42B,72B,87C,187C,245C,292C,304C,310C,368C 'new':355C 'notif':121C,125C,128C,132C,206C,211C,307C 'notifi':79B,296C,327C,339C 'null':336C 'object':196C 'onlin':127C,131C,210C 'outright':329C 'pass':44B 'path':63B,283C 'pf1550':24B 'plug/unplug':255C 'pointer':37B,55B,119C,215C,228C 'privileg':266C 'prop':101C,123C,130C,141C,163C,201C,204C,209C,315C,350C 'properti':38B,154C,158C,221C,328C,356C 'propval':107C 'provid':280C 're':360C 're-review':359C 'read':62B,282C 'reject':324C 'result':257C 'review':361C 'run':242C 'safeti':369C 'set':80B,140C,153C,200C,314C 'sinc':337C 'state':249C,342C 'status':120C,124C,205C 'store':52B,171C,226C 'supervisor':82B,244C,300C,309C 'supervisor-mod':308C 'suppli':146C,333C 'suppress':305C 'syscal':88C 'thread':6A,43B,50B,76B,188C,270C,301C 'two':34B,112C,326C 'unaffect':318C 'union':105C,116C,147C,364C 'unprivileg':49B,269C 'user':5A,41B,71B,75B,86C,178C,186C,291C,303C,367C 'user-mod':40B,85C,185C,366C 'user/kernel':110C 'userspac':182C,276C 'valu':216C 'verbatim':148C 'verifi':89C,323C 'vrfi':138C,160C 'work':239C 'z':137C,159C 'zephyr':1A,25B,26B","nicknames":[],"mitigations":[],"who_affected":"Only firmware built on Zephyr with CONFIG_USERSPACE enabled, where user-mode threads are granted access to a charger device, is exposed. Firmware with CONFIG_USERSPACE disabled, or where only supervisor-mode code calls the charger API, is not affected, and boards without the three listed charger drivers are outside the affected code paths.","tier":"B","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"businesses","plain_action":null,"pkeys":[],"ptokens":[],"labels":["bq2518x","chargerdrivers","embedded","high","infrastructure","max20335","pf1550","zephyr"],"campaign_type":null,"search_a":"'-2026':12A,15A '-91007':13A,16A 'charger':2A 'control':9A 'cve':11A,14A 'driver':3A 'flow':10A 'hijack':7A 'kernel':8A 'let':4A 'thread':6A 'user':5A 'zephyr':1A","search_b":"'address':69B 'also':64B 'api':30B 'arbitrari':54B 'bq2518x':17B 'call':60B 'charger':19B,28B 'charger-driv':18B 'check':33B 'clear':78B 'code':68B,83B 'driver':20B,29B 'embed':21B 'function':36B 'function-point':35B 'infrastructur':22B 'kernel':58B,67B 'later':59B 'leak':65B 'max20335':23B 'mode':42B,72B 'notifi':79B 'pass':44B 'path':63B 'pf1550':24B 'pointer':37B,55B 'properti':38B 'read':62B 'set':80B 'store':52B 'supervisor':82B 'thread':43B,50B,76B 'two':34B 'unprivileg':49B 'user':41B,71B,75B 'user-mod':40B 'zephyr':25B,26B","search_c":"'/charger_get_prop':316C 'across':108C 'add':344C 'addit':284C 'address':174C,289C 'api':94C 'arbitrari':214C 'argument':102C 'assert':347C 'back':175C 'boundari':111C 'build':346C 'cabl':254C 'call':198C 'callback':155C,173C,334C 'caller':145C,311C 'caller-suppli':144C 'chang':250C 'charger':92C,106C,122C,129C,139C,161C,194C,199C,203C,208C,248C,306C,313C,349C 'clear':294C 'code':288C 'common':351C 'config':181C,275C 'control':261C 'control-flow':260C 'copi':104C,169C 'could':197C 'count':352C 'data':231C 'declar':133C 'defeat':271C 'defect':167C 'devic':195C,230C,341C 'disclos':285C 'driver':93C,151C,217C 'drivers/charger/charger_bq2518x.c':225C 'drivers/charger/charger_handlers.c':96C 'drivers/charger/charger_max20335.c':222C 'drivers/charger/charger_pf1550.c':223C 'enabl':183C 'fix':320C 'flow':262C 'forc':357C 'forward':142C 'function':118C 'get':162C 'grant':192C 'handler':240C 'hijack':263C 'implement':219C 'includ':330C 'include/zephyr/drivers/charger.h':135C 'inspect':99C 'instal':297C 'interrupt':238C 'invok':234C 'isol':273C 'kernel':172C,265C,287C 'later':233C 'let':302C 'make':321C 'meant':278C 'member':113C 'memori':179C 'mirror':166C 'mode':87C,187C,245C,292C,304C,310C,368C 'new':355C 'notif':121C,125C,128C,132C,206C,211C,307C 'notifi':296C,327C,339C 'null':336C 'object':196C 'onlin':127C,131C,210C 'outright':329C 'path':283C 'plug/unplug':255C 'pointer':119C,215C,228C 'privileg':266C 'prop':101C,123C,130C,141C,163C,201C,204C,209C,315C,350C 'properti':154C,158C,221C,328C,356C 'propval':107C 'provid':280C 're':360C 're-review':359C 'read':282C 'reject':324C 'result':257C 'review':361C 'run':242C 'safeti':369C 'set':140C,153C,200C,314C 'sinc':337C 'state':249C,342C 'status':120C,124C,205C 'store':171C,226C 'supervisor':244C,300C,309C 'supervisor-mod':308C 'suppli':146C,333C 'suppress':305C 'syscal':88C 'thread':188C,270C,301C 'two':112C,326C 'unaffect':318C 'union':105C,116C,147C,364C 'unprivileg':269C 'user':86C,178C,186C,291C,303C,367C 'user-mod':85C,185C,366C 'user/kernel':110C 'userspac':182C,276C 'valu':216C 'verbatim':148C 'verifi':89C,323C 'vrfi':138C,160C 'work':239C 'z':137C,159C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-12T14:58:27+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","cvss_by":"vulnerabilities@zephyrproject.org","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-91007","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-91007","severity":null,"published_at":"2026-11-12T16:19:21+00:00","modified_at":"2026-11-12T16:19:21+00:00","first_seen_at":"2026-11-12T16:44:02+00:00","fetched_at":"2026-11-12T16:44:02+00:00","note":null}],"documents":[{"id":136558,"url":"https://github.com/zephyrproject-rtos/zephyr/commit/5467b7a73fe093d7e9562ee15c321cf8f1639d17","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":136559,"url":"https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-jr35-f52j-fm88","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-11-12T14:58:27+00:00","relation":"advisory","confidence":null,"note":"Vendor advisory: github.com"}],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}