{"id":"CVE-2026-19809","kind":"vulnerability","aliases":["CVE-2026-19809"],"related":[],"title":"Zephyr: charger property syscall leaks kernel stack bytes to user threads","description":"The user-mode system call verifier z_vrfy_charger_get_prop() in drivers/charger/charger_handlers.c declares an uninitialized union charger_propval k_val on the kernel (privileged) stack, passes it to the charger driver back end via z_impl_charger_get_prop(), and then copies the full sizeof(union charger_propval) back into the calling user thread's buffer with k_usermode_to_copy(). That discloses kernel stack contents on two paths:\n\nOn error. The copy-out ignores the driver's return code. In-tree back ends return an error without writing through the value pointer for properties they do not implement: charger_gpio_get_prop() returns -ENOTSUP unconditionally, and bq24190_get_prop() has a default: return -ENOTSUP; arm that never touches val. The whole union is then stack residue.\nOn success. A back end writes only the one union member the requested property selects (for example sbs_charger.c writes the one-byte val->present for CHARGER_PROP_PRESENT and returns 0), yet the handler still copies the whole union, so every byte beyond that member is uninitialized.\n\nThe handler is compiled only when CONFIG_USERSPACE=y and is reachable by any user-mode thread that has been granted access to a charger device object. K_SYSCALL_DRIVER_CHARGER() validates only the device object and its API pointer, not the property identifier, so an unprivileged thread can choose prop freely: an unimplemented property forces the error path, a narrow one the success path, and the call can be repeated at will.\n\nEach call discloses up to the size of the union (12 bytes on a 32-bit target, 16 bytes on 64-bit targets where the function-pointer members widen it) of supervisor-stack memory. The bytes are residue of earlier kernel-side frames on the thread's privileged stack and can contain kernel object addresses and saved return addresses, which an unprivileged thread cannot otherwise observe and which help defeat address-layout assumptions when exploiting a separate memory-safety defect. There is no integrity or availability impact.\n\nTwo commits fix it, and both are needed. 5054384e983c skips the copy-out when the back end reports an error. c31cac727d02 zeroes the union before the driver call, so the bytes copied out on success are driver-written data or zeros. A tree carrying only the first still leaks on every successful call.","summary":"The Zephyr charger driver's user-mode syscall copies an uninitialized kernel-stack union back to the calling thread. An unprivileged thread with access to a charger device can read leftover supervisor-stack bytes, which may include kernel addresses.","severity":"low","cvss":3.3,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["charger-driver","embedded","runtime","user-mode","zephyr"],"not_affected_if":["no-charger-driver","no-user-threads-with-charger-access","no-userspace"],"how_to_check":"- Check whether the build sets `CONFIG_USERSPACE=y` and enables a charger driver.\n- Check whether the Zephyr tree includes commit `5054384e983c` and commit `c31cac727d02`.\n- Confirm the running Zephyr version against the fixed versions in the product ranges, which the sources do not list.","fix":"- Zephyr: apply commits `5054384e983c` and `c31cac727d02`; both are needed. Fixed release version: unknown.","status":"open","published_at":"2026-11-12T16:19:08+00:00","first_seen_at":"2026-11-12T16:44:02+00:00","triaged_at":"2026-11-12T16:45:46+00:00","updated_at":"2026-11-12T16:45:46+00:00","category":"runtime","confidence":0.8,"triage":{"at":"2026-11-12T16:45:46Z","model":"claude-haiku-5-5","output":{"fix":"- Zephyr: apply commits `5054384e983c` and `c31cac727d02`; both are needed. Fixed release version: unknown.","reach":"local","title":"Zephyr: charger property syscall leaks kernel stack bytes to user threads","impact":"low","summary":"The Zephyr charger driver's user-mode syscall copies an uninitialized kernel-stack union back to the calling thread. An unprivileged thread with access to a charger device can read leftover supervisor-stack bytes, which may include kernel addresses.","audience":"businesses","category":"runtime","nicknames":[],"who_cares":["zephyr","embedded","charger-driver","user-mode"],"confidence":0.8,"fix_status":"available","needs_auth":"yes","worst_case":"unprivileged thread reads kernel stack residue, possibly kernel addresses","analyst_note":"","how_to_check":"- Check whether the build sets `CONFIG_USERSPACE=y` and enables a charger driver.\n- Check whether the Zephyr tree includes commit `5054384e983c` and commit `c31cac727d02`.\n- Confirm the running Zephyr version against the fixed versions in the product ranges, which the sources do not list.","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["no-userspace","no-charger-driver","no-user-threads-with-charger-access"],"who_is_affected":"Only builds that enable user mode (CONFIG_USERSPACE=y) and grant user-mode threads access to a charger device object are exposed. The leak happens on every call that reaches the handler, whether the driver returns an error or success, so a tree with only the first commit still leaks on successful calls. Systems without a charger driver or without user-mode threads can skip it.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"low"},"cost_usd":0.000855,"input_tokens":5280,"output_tokens":653,"severity_before":"low"},"analyst_status":null,"analyst_note":null,"search":"'-19809':14A,17A '-2026':13A,16A '0':232C '12':333C '16':340C '32':337C '5054384e983':423C '64':343C 'access':52B,271C 'address':68B,380C,384C,397C 'address-layout':396C 'api':288C 'arm':188C 'assumpt':399C 'avail':413C 'back':43B,102C,119C,155C,203C,432C 'beyond':244C 'bit':338C,344C 'bq24190':180C 'buffer':126C 'byte':8A,63B,223C,243C,334C,341C,360C,447C 'c':424C 'c31cac727d02':437C 'call':46B,74C,122C,317C,324C,444C,470C 'cannot':389C 'carri':461C 'charger':2A,19B,29B,55B,78C,87C,100C,107C,117C,172C,227C,274C,280C 'charger-driv':18B 'charger.c':218C 'choos':299C 'code':151C 'commit':416C 'compil':252C 'config':255C 'contain':377C 'content':136C 'copi':36B,112C,131C,144C,237C,428C,448C 'copy-out':143C,427C 'cve':12A,15A 'data':456C 'declar':83C 'default':185C 'defeat':395C 'defect':407C 'devic':56B,275C,284C 'disclos':133C,325C 'driver':20B,30B,101C,148C,279C,443C,454C 'driver-written':453C 'drivers/charger/charger_handlers.c':82C 'earlier':364C 'embed':21B 'end':103C,156C,204C,433C 'enotsup':177C,187C 'error':141C,159C,307C,436C 'everi':242C,468C 'exampl':216C 'exploit':401C 'first':464C 'fix':417C 'forc':305C 'frame':368C 'freeli':301C 'full':114C 'function':349C 'function-point':348C 'get':79C,108C,174C,181C 'gpio':173C 'grant':270C 'handler':235C,250C 'help':394C 'identifi':293C 'ignor':146C 'impact':414C 'impl':106C 'implement':171C 'in-tre':152C 'includ':66B 'integr':411C 'k':89C,128C,277C 'kernel':6A,40B,67B,93C,134C,366C,378C 'kernel-sid':365C 'kernel-stack':39B 'layout':398C 'leak':5A,466C 'leftov':59B 'may':65B 'member':210C,246C,351C 'memori':358C,405C 'memory-safeti':404C 'mode':25B,34B,72C,265C 'narrow':310C 'need':422C 'never':190C 'object':276C,285C,379C 'observ':391C 'one':208C,222C,311C 'one-byt':221C 'otherwis':390C 'pass':96C 'path':139C,308C,314C 'pointer':165C,289C,350C 'present':225C,229C 'privileg':94C,373C 'prop':80C,109C,175C,182C,228C,300C 'properti':3A,167C,213C,292C,304C 'propval':88C,118C 'reachabl':260C 'read':58B 'repeat':320C 'report':434C 'request':212C 'residu':199C,362C 'return':150C,157C,176C,186C,231C,383C 'runtim':22B 'safeti':406C 'save':382C 'sbs':217C 'select':214C 'separ':403C 'side':367C 'size':329C 'sizeof':115C 'skip':425C 'stack':7A,41B,62B,95C,135C,198C,357C,374C 'still':236C,465C 'success':201C,313C,451C,469C 'supervisor':61B,356C 'supervisor-stack':60B,355C 'syscal':4A,35B,278C 'system':73C 'target':339C,345C 'thread':11A,47B,50B,124C,266C,297C,371C,388C 'touch':191C 'tree':154C,460C 'two':138C,415C 'uncondit':178C 'unimpl':303C 'uniniti':38B,85C,248C 'union':42B,86C,116C,195C,209C,240C,332C,440C 'unprivileg':49B,296C,387C 'user':10A,24B,33B,71C,123C,264C 'user-mod':23B,32B,70C,263C 'usermod':129C 'userspac':256C 'val':90C,192C,224C 'valid':281C 'valu':164C 'verifi':75C 'via':104C 'vrfi':77C 'whole':194C,239C 'widen':352C 'without':160C 'write':161C,205C,219C 'written':455C 'y':257C 'yet':233C 'z':76C,105C 'zephyr':1A,26B,28B 'zero':438C,458C","nicknames":[],"mitigations":[],"who_affected":"Only builds that enable user mode (CONFIG_USERSPACE=y) and grant user-mode threads access to a charger device object are exposed. The leak happens on every call that reaches the handler, whether the driver returns an error or success, so a tree with only the first commit still leaks on successful calls. Systems without a charger driver or without user-mode threads can skip it.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"businesses","plain_action":null,"pkeys":[],"ptokens":[],"labels":["chargerdriver","embedded","low","runtime","usermode","zephyr"],"campaign_type":null,"search_a":"'-19809':14A,17A '-2026':13A,16A 'byte':8A 'charger':2A 'cve':12A,15A 'kernel':6A 'leak':5A 'properti':3A 'stack':7A 'syscal':4A 'thread':11A 'user':10A 'zephyr':1A","search_b":"'access':52B 'address':68B 'back':43B 'byte':63B 'call':46B 'charger':19B,29B,55B 'charger-driv':18B 'copi':36B 'devic':56B 'driver':20B,30B 'embed':21B 'includ':66B 'kernel':40B,67B 'kernel-stack':39B 'leftov':59B 'may':65B 'mode':25B,34B 'read':58B 'runtim':22B 'stack':41B,62B 'supervisor':61B 'supervisor-stack':60B 'syscal':35B 'thread':47B,50B 'uniniti':38B 'union':42B 'unprivileg':49B 'user':24B,33B 'user-mod':23B,32B 'zephyr':26B,28B","search_c":"'0':232C '12':333C '16':340C '32':337C '5054384e983':423C '64':343C 'access':271C 'address':380C,384C,397C 'address-layout':396C 'api':288C 'arm':188C 'assumpt':399C 'avail':413C 'back':102C,119C,155C,203C,432C 'beyond':244C 'bit':338C,344C 'bq24190':180C 'buffer':126C 'byte':223C,243C,334C,341C,360C,447C 'c':424C 'c31cac727d02':437C 'call':74C,122C,317C,324C,444C,470C 'cannot':389C 'carri':461C 'charger':78C,87C,100C,107C,117C,172C,227C,274C,280C 'charger.c':218C 'choos':299C 'code':151C 'commit':416C 'compil':252C 'config':255C 'contain':377C 'content':136C 'copi':112C,131C,144C,237C,428C,448C 'copy-out':143C,427C 'data':456C 'declar':83C 'default':185C 'defeat':395C 'defect':407C 'devic':275C,284C 'disclos':133C,325C 'driver':101C,148C,279C,443C,454C 'driver-written':453C 'drivers/charger/charger_handlers.c':82C 'earlier':364C 'end':103C,156C,204C,433C 'enotsup':177C,187C 'error':141C,159C,307C,436C 'everi':242C,468C 'exampl':216C 'exploit':401C 'first':464C 'fix':417C 'forc':305C 'frame':368C 'freeli':301C 'full':114C 'function':349C 'function-point':348C 'get':79C,108C,174C,181C 'gpio':173C 'grant':270C 'handler':235C,250C 'help':394C 'identifi':293C 'ignor':146C 'impact':414C 'impl':106C 'implement':171C 'in-tre':152C 'integr':411C 'k':89C,128C,277C 'kernel':93C,134C,366C,378C 'kernel-sid':365C 'layout':398C 'leak':466C 'member':210C,246C,351C 'memori':358C,405C 'memory-safeti':404C 'mode':72C,265C 'narrow':310C 'need':422C 'never':190C 'object':276C,285C,379C 'observ':391C 'one':208C,222C,311C 'one-byt':221C 'otherwis':390C 'pass':96C 'path':139C,308C,314C 'pointer':165C,289C,350C 'present':225C,229C 'privileg':94C,373C 'prop':80C,109C,175C,182C,228C,300C 'properti':167C,213C,292C,304C 'propval':88C,118C 'reachabl':260C 'repeat':320C 'report':434C 'request':212C 'residu':199C,362C 'return':150C,157C,176C,186C,231C,383C 'safeti':406C 'save':382C 'sbs':217C 'select':214C 'separ':403C 'side':367C 'size':329C 'sizeof':115C 'skip':425C 'stack':95C,135C,198C,357C,374C 'still':236C,465C 'success':201C,313C,451C,469C 'supervisor':356C 'supervisor-stack':355C 'syscal':278C 'system':73C 'target':339C,345C 'thread':124C,266C,297C,371C,388C 'touch':191C 'tree':154C,460C 'two':138C,415C 'uncondit':178C 'unimpl':303C 'uniniti':85C,248C 'union':86C,116C,195C,209C,240C,332C,440C 'unprivileg':296C,387C 'user':71C,123C,264C 'user-mod':70C,263C 'usermod':129C 'userspac':256C 'val':90C,192C,224C 'valid':281C 'valu':164C 'verifi':75C 'via':104C 'vrfi':77C 'whole':194C,239C 'widen':352C 'without':160C 'write':161C,205C,219C 'written':455C 'y':257C 'yet':233C 'z':76C,105C 'zero':438C,458C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-12T15:17:40+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N","cvss_by":"vulnerabilities@zephyrproject.org","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-19809","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-19809","severity":null,"published_at":"2026-11-12T16:19:08+00:00","modified_at":"2026-11-12T16:19:09+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":136553,"url":"https://github.com/zephyrproject-rtos/zephyr/commit/5054384e983c105b90d704272abcd479486ae3a2","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":136554,"url":"https://github.com/zephyrproject-rtos/zephyr/commit/c31cac727d029f273a67f65941985696f1882867","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":136555,"url":"https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-rghm-r3c9-92qc","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-11-12T15:17:40+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"}