{"id":"CVE-2026-90833","kind":"vulnerability","aliases":["CVE-2026-90833"],"related":[],"title":"Zephyr: simulated EEPROM driver lets a user thread write kernel memory","description":"The simulated EEPROM driver validated access ranges in eeprom_range_is_valid() (drivers/eeprom/eeprom_simulator.c) with a single test, (offset + len) <= config->size. Because offset is a signed off_t and len an unsigned size_t of the same rank, the addition is evaluated in unsigned arithmetic: a negative offset combined with a compensating len wraps the sum back into the accepted range. eeprom_sim_read() and eeprom_sim_write() then memcpy() through the EEPROM(addr) macro, which is plain pointer arithmetic on the driver's static mock_eeprom array, so the copy addresses memory located before that array.\n\neeprom_read() and eeprom_write() are __syscall entry points, and their verification handlers in drivers/eeprom/eeprom_handlers.c check only the device object and the caller's own data buffer (K_SYSCALL_MEMORY_READ/K_SYSCALL_MEMORY_WRITE) — the offset argument is passed to the driver unvalidated. With CONFIG_USERSPACE=y, a CONFIG_EEPROM_SIMULATOR device instance, and the device object granted to a user thread (the usage the in-tree tests/drivers/eeprom/api suite exercises from ZTEST_USER threads), an unprivileged thread could supply a negative offset and have the kernel perform the copy on its behalf.\n\nThe result is an out-of-bounds read of kernel .bss returned into the caller's buffer and, via the write path, an out-of-bounds write of caller-supplied bytes over kernel memory preceding mock_eeprom. Both the start address and the length of the affected span are attacker-selected, so the primitive is sufficient to corrupt adjacent kernel state and escape the user-mode sandbox. Exposure is limited to builds that instantiate the simulated EEPROM (status = \"okay\" by default on qemu_x86 and native_sim, otherwise added by a devicetree overlay) together with userspace isolation.\n\nThe fix rejects negative offsets and performs the remaining bound check without overflow.","summary":"Zephyr's simulated EEPROM driver checks (offset + len) <= size in unsigned arithmetic, so a negative offset wraps past validation. A user-mode thread can then read or write kernel memory before the mock_eeprom array through the eeprom_read/eeprom_write syscalls. Fixed in 4.3.2 and 4.5.0.","severity":"high","cvss":7.8,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"zephyr","fixed":["4.3.2","4.5.0"],"affected":">= 2.2.0, < 4.3.2; >= 4.4.0, < 4.5.0","ecosystem":"vendor"}],"ecosystems":[],"tags":["embedded","runtime","userspace","zephyr"],"not_affected_if":["hardware-eeprom-only","no-eeprom-simulator","no-userspace"],"how_to_check":"- Your build is exposed only if all hold: CONFIG_EEPROM_SIMULATOR=y (default y when a zephyr,sim-eeprom node is enabled), CONFIG_USERSPACE=y, and the EEPROM device is granted to user threads (k_object_access_grant).\n- Check the devicetree: the sim-eeprom node has status = \"okay\" (default on qemu_x86 and native_sim, otherwise added by overlay).\n- Check your Zephyr version: affected >= 2.2.0 and < 4.3.2, or >= 4.4.0 and < 4.5.0.\n- Also check any local branch: drivers/eeprom/eeprom_simulator.c should reject offset < 0 in eeprom_range_is_valid().","fix":"Upgrade Zephyr to 4.3.2 (4.3 line) or 4.5.0. Patch commit ce2ec9b3a34d (main PR #118774); backport PRs merged to v4.4-branch (#119415), v4.3-branch (#119414), v3.7-branch (#119416), but the advisory lists patched releases only as 4.3.2 and 4.5.0. 4.4.x before 4.5.0 stays listed as affected.","status":"open","published_at":"2026-11-10T22:21:14+00:00","first_seen_at":"2026-11-10T22:27:31+00:00","triaged_at":"2026-11-10T22:29:09+00:00","updated_at":"2026-11-10T22:37:48+00:00","category":"runtime","confidence":0.9,"triage":{"at":"2026-11-10T22:29:09Z","model":"claude-haiku-5-5","output":{"fix":"unknown","reach":"local","title":"Zephyr: simulated EEPROM driver lets a user thread write kernel memory","impact":"high","summary":"The simulated EEPROM driver's range check in Zephyr lets a negative offset wrap past validation, so a user-mode thread can make the kernel read or write memory before the EEPROM buffer. That gives an unprivileged thread a path to corrupt kernel state and escape the user-mode sandbox.","audience":"developers","category":"runtime","nicknames":[],"who_cares":["zephyr","embedded","userspace"],"confidence":0.7,"fix_status":"unknown","needs_auth":"yes","worst_case":"Unprivileged thread corrupts kernel memory and escapes user-mode sandbox","analyst_note":"Confirm the fixed Zephyr version and the patch commit from the linked fix and advisory pages; the sources did not state them.","how_to_check":"- Check whether the build enables `CONFIG_EEPROM_SIMULATOR` and `CONFIG_USERSPACE=y`.\n- Check whether the EEPROM device object is granted to user threads.\n- Check whether the EEPROM simulator device is enabled in the devicetree (`status = \"okay\"` by default on qemu_x86 and native_sim).","plain_action":"","product_name":"","needs_analyst":true,"not_affected_if":["no-eeprom-simulator","no-userspace","hardware-eeprom-only"],"who_is_affected":"Only builds that include the simulated EEPROM driver together with userspace isolation are exposed. The simulator is enabled by default on qemu_x86 and native_sim, and otherwise is added by a devicetree overlay. Builds without the simulator or without userspace can skip it.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"high"},"cost_usd":0.000837,"input_tokens":5194,"output_tokens":636,"severity_before":"high"},"analyst_status":"done","analyst_note":"Confirm the fixed Zephyr version and the patch commit from the linked fix and advisory pages; the sources did not state them.","search":"'-2026':13A,16A '-90833':14A,17A '4.3.2':66B '4.5.0':68B 'accept':128C 'access':74C 'add':349C 'addit':108C 'addr':142C 'address':160C,299C 'adjac':318C 'affect':305C 'argument':199C 'arithmet':34B,113C,148C 'array':58B,156C,165C 'attack':309C 'attacker-select':308C 'back':125C 'behalf':255C 'bound':263C,283C,367C 'bss':267C 'buffer':192C,273C 'build':332C 'byte':289C 'caller':188C,271C,287C 'caller-suppli':286C 'check':28B,181C,368C 'combin':117C 'compens':120C 'config':88C,207C,211C 'copi':159C,252C 'corrupt':317C 'could':241C 'cve':12A,15A 'data':191C 'default':341C 'devic':184C,214C,218C 'devicetre':352C 'driver':4A,27B,72C,151C,204C 'drivers/eeprom/eeprom_handlers.c':180C 'drivers/eeprom/eeprom_simulator.c':81C 'eeprom':3A,26B,57B,61B,71C,77C,130C,134C,141C,155C,166C,169C,212C,295C,337C 'embed':19B 'entri':173C 'escap':322C 'evalu':110C 'exercis':233C 'exposur':328C 'fix':64B,359C 'grant':220C 'handler':178C 'in-tre':228C 'instanc':215C 'instanti':334C 'isol':357C 'k':193C 'kernel':10A,52B,249C,266C,291C,319C 'len':30B,87C,98C,121C 'length':302C 'let':5A 'limit':330C 'locat':162C 'macro':143C 'memcpi':138C 'memori':11A,53B,161C,195C,292C 'mock':56B,154C,294C 'mode':45B,326C 'nativ':346C 'negat':37B,115C,244C,361C 'object':185C,219C 'offset':29B,38B,86C,91C,116C,198C,245C,362C 'okay':339C 'otherwis':348C 'out-of-bound':260C,280C 'overflow':370C 'overlay':353C 'pass':201C 'past':40B 'path':278C 'perform':250C,364C 'plain':146C 'point':174C 'pointer':147C 'preced':293C 'primit':313C 'qemu':343C 'rang':75C,78C,129C 'rank':106C 'read':49B,132C,167C,264C 'read/eeprom_write':62B 'read/k_syscall_memory_write':196C 'reject':360C 'remain':366C 'result':257C 'return':268C 'runtim':20B 'sandbox':327C 'select':310C 'sign':94C 'sim':131C,135C,347C 'simul':2A,25B,70C,213C,336C 'singl':84C 'size':31B,89C,101C 'span':306C 'start':298C 'state':320C 'static':153C 'status':338C 'suffici':315C 'suit':232C 'sum':124C 'suppli':242C,288C 'syscal':63B,172C,194C 'test':85C 'tests/drivers/eeprom/api':231C 'thread':8A,46B,224C,237C,240C 'togeth':354C 'tree':230C 'unprivileg':239C 'unsign':33B,100C,112C 'unvalid':205C 'usag':226C 'user':7A,44B,223C,236C,325C 'user-mod':43B,324C 'userspac':21B,208C,356C 'valid':41B,73C,80C 'verif':177C 'via':275C 'without':369C 'wrap':39B,122C 'write':9A,51B,136C,170C,277C,284C 'x86':344C 'y':209C 'zephyr':1A,18A,22B,23B 'ztest':235C","nicknames":[],"mitigations":[],"who_affected":"Only builds that include the simulated EEPROM driver together with userspace isolation are exposed. The simulator is enabled by default on qemu_x86 and native_sim, and otherwise is added by a devicetree overlay. Builds without the simulator or without userspace can skip it.","tier":"B","verified":{"fix":{"at":"2026-11-10T22:37:48Z","by":"analyst","doc":"https://github.com/zephyrproject-rtos/zephyr/commit/ce2ec9b3a34d71f52f5d1d7491b91393e334713e","run_id":3012},"products":{"at":"2026-11-10T22:37:48Z","by":"analyst","doc":"https://github.com/zephyrproject-rtos/zephyr/commit/ce2ec9b3a34d71f52f5d1d7491b91393e334713e","run_id":3012},"how_to_check":{"at":"2026-11-10T22:37:48Z","by":"analyst","doc":"https://github.com/zephyrproject-rtos/zephyr/commit/ce2ec9b3a34d71f52f5d1d7491b91393e334713e","run_id":3012},"who_affected":{"at":"2026-11-10T22:37:48Z","by":"analyst","doc":"https://github.com/zephyrproject-rtos/zephyr/commit/ce2ec9b3a34d71f52f5d1d7491b91393e334713e","run_id":3012}},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":["zephyr"],"ptokens":["zephyr"],"labels":["embedded","high","runtime","userspace","zephyr"],"campaign_type":null,"search_a":"'-2026':13A,16A '-90833':14A,17A 'cve':12A,15A 'driver':4A 'eeprom':3A 'kernel':10A 'let':5A 'memori':11A 'simul':2A 'thread':8A 'user':7A 'write':9A 'zephyr':1A,18A","search_b":"'4.3.2':66B '4.5.0':68B 'arithmet':34B 'array':58B 'check':28B 'driver':27B 'eeprom':26B,57B,61B 'embed':19B 'fix':64B 'kernel':52B 'len':30B 'memori':53B 'mock':56B 'mode':45B 'negat':37B 'offset':29B,38B 'past':40B 'read':49B 'read/eeprom_write':62B 'runtim':20B 'simul':25B 'size':31B 'syscal':63B 'thread':46B 'unsign':33B 'user':44B 'user-mod':43B 'userspac':21B 'valid':41B 'wrap':39B 'write':51B 'zephyr':22B,23B","search_c":"'accept':128C 'access':74C 'add':349C 'addit':108C 'addr':142C 'address':160C,299C 'adjac':318C 'affect':305C 'argument':199C 'arithmet':113C,148C 'array':156C,165C 'attack':309C 'attacker-select':308C 'back':125C 'behalf':255C 'bound':263C,283C,367C 'bss':267C 'buffer':192C,273C 'build':332C 'byte':289C 'caller':188C,271C,287C 'caller-suppli':286C 'check':181C,368C 'combin':117C 'compens':120C 'config':88C,207C,211C 'copi':159C,252C 'corrupt':317C 'could':241C 'data':191C 'default':341C 'devic':184C,214C,218C 'devicetre':352C 'driver':72C,151C,204C 'drivers/eeprom/eeprom_handlers.c':180C 'drivers/eeprom/eeprom_simulator.c':81C 'eeprom':71C,77C,130C,134C,141C,155C,166C,169C,212C,295C,337C 'entri':173C 'escap':322C 'evalu':110C 'exercis':233C 'exposur':328C 'fix':359C 'grant':220C 'handler':178C 'in-tre':228C 'instanc':215C 'instanti':334C 'isol':357C 'k':193C 'kernel':249C,266C,291C,319C 'len':87C,98C,121C 'length':302C 'limit':330C 'locat':162C 'macro':143C 'memcpi':138C 'memori':161C,195C,292C 'mock':154C,294C 'mode':326C 'nativ':346C 'negat':115C,244C,361C 'object':185C,219C 'offset':86C,91C,116C,198C,245C,362C 'okay':339C 'otherwis':348C 'out-of-bound':260C,280C 'overflow':370C 'overlay':353C 'pass':201C 'path':278C 'perform':250C,364C 'plain':146C 'point':174C 'pointer':147C 'preced':293C 'primit':313C 'qemu':343C 'rang':75C,78C,129C 'rank':106C 'read':132C,167C,264C 'read/k_syscall_memory_write':196C 'reject':360C 'remain':366C 'result':257C 'return':268C 'sandbox':327C 'select':310C 'sign':94C 'sim':131C,135C,347C 'simul':70C,213C,336C 'singl':84C 'size':89C,101C 'span':306C 'start':298C 'state':320C 'static':153C 'status':338C 'suffici':315C 'suit':232C 'sum':124C 'suppli':242C,288C 'syscal':172C,194C 'test':85C 'tests/drivers/eeprom/api':231C 'thread':224C,237C,240C 'togeth':354C 'tree':230C 'unprivileg':239C 'unsign':100C,112C 'unvalid':205C 'usag':226C 'user':223C,236C,325C 'user-mod':324C 'userspac':208C,356C 'valid':73C,80C 'verif':177C 'via':275C 'without':369C 'wrap':122C 'write':136C,170C,277C,284C 'x86':344C 'y':209C 'ztest':235C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-10T21:54:59+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-90833","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-90833","severity":null,"published_at":"2026-11-10T22:21:14+00:00","modified_at":"2026-11-10T22:21:14+00:00","first_seen_at":"2026-11-10T22:27:31+00:00","fetched_at":"2026-11-10T22:27:31+00:00","note":null},{"source":"analyst","external_id":"CVE-2026-90833:3012","url":null,"severity":null,"published_at":"2026-11-10T22:37:48+00:00","modified_at":"2026-11-10T22:37:48+00:00","first_seen_at":"2026-11-10T22:37:48+00:00","fetched_at":"2026-11-10T22:37:48+00:00","note":"Read GHSA-vf6j-hcx8-44vh and commit ce2ec9b: patched 4.3.2/4.5.0, affected ranges stated; no exploitation or PoC found (not searched social; obscure embedded CVE)."}],"documents":[{"id":119554,"url":"https://github.com/zephyrproject-rtos/zephyr/commit/ce2ec9b3a34d71f52f5d1d7491b91393e334713e","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":119555,"url":"https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-vf6j-hcx8-44vh","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-11-10T21:54:59+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"}