CVE-2026-19669
Beschrijving NL
De syscall-verificateurs in de gebruikersmodus z_vrfy_fuel_gauge_get_props() en z_vrfy_fuel_gauge_set_props() in drivers/fuel_gauge/fuel_gauge_syscall_handlers.c hebben twee arrays met variabele lengte gedeclareerd, union fuel_gauge_prop_val k_vals[len] en fuel_gauge_prop_t k_props[len], rechtstreeks gesorteerd op basis van het door de beller geleverde len-argument. len is een niet-gevalideerde size_t rechtstreeks afkomstig van de syscall abi, en de vla's werden toegewezen vóór enige controle — inclusief vóór de K_SYSCALL_DRIVER_FUEL_GAUGE() object-toegangscontrole. De daaropvolgende k_usermode_from_copy() -aanroepen hebben alleen gevalideerd dat de bronbuffer van de gebruiker leesbaar was; de kernelbestemming is nooit beperkt gecontroleerd, omdat deze werd gedimensioneerd door dezelfde aanvaller - gekozen len. Elke thread die in de gebruikersmodus wordt uitgevoerd met CONFIG_USERSPACE ingeschakeld, kan fuel_gauge_get_props() of fuel_gauge_set_props() aanroepen met een grote lengte. Dit verplaatst eerst de aanwijzer van de supervisor-stapel door een willekeurig door de aanvaller gekozen hoeveelheid — Zephyr bouwt niet met stack-clash-sondering, dus de verplaatsing zelf is niet foutief en de geneste oproepen van de verificateur schrijven vervolgens frames onder de geprivilegieerde stapel. Als de beller toegang heeft gekregen tot een object van een brandstofmeter, schrijft de memcpy in k_usermode_FROM_copy() bovendien len * sizeof(union fuel_gauge_prop_val) bytes van volledig door de aanvaller gecontroleerde gegevens die ver onder de stapelbasis beginnen. CONFIG_PRIVILEGED_STACK_SIZE is standaard ingesteld op 1024 bytes, dus een lengte van ongeveer 170 is al voldoende. Het resultaat is een out-of-bounds schrijven in supervisor-modus met aanvaller-gecontroleerde lengte en, op het toegestane pad, aanvaller-gecontroleerde inhoud — een uitbraak van de gebruikersmodus sandbox in kernelgeheugen, wat leidt tot uitvoering van kernelcode of een systeemcrash. Een stapelbewakingsgebied bevat het niet, omdat de kopie onder de bewaker begint en naar boven loopt, waardoor onbeschermd geheugen wordt beschadigd voordat de bewaker wordt bereikt. De fix verwijdert de kopieën aan de kernelzijde volledig en valideert de arrays van de beller met K_SYSCALL_MEMORY_ARRAY_READ() / K_SYSCALL_MEMORY_ARRAY_WRITE(), die ook de len * size multiplication overflow afhandelen; dit is veilig omdat noch fuel_gauge_prop_t noch union fuel_gauge_prop_val ingesloten wijzers bevat.
Origineel (Engels) tonen
The user-mode syscall verifiers z_vrfy_fuel_gauge_get_props() and z_vrfy_fuel_gauge_set_props() in drivers/fuel_gauge/fuel_gauge_syscall_handlers.c declared two variable-length arrays, union fuel_gauge_prop_val k_vals[len] and fuel_gauge_prop_t k_props[len], sized directly by the caller-supplied len argument. len is an unvalidated size_t taken straight from the syscall ABI, and the VLAs were allocated before any check at all — including before the K_SYSCALL_DRIVER_FUEL_GAUGE() object-permission check. The subsequent k_usermode_from_copy() calls validated only that the user source buffer was readable; the kernel destination was never bounds-checked, since it was sized by the same attacker-chosen len.
Any thread running in user mode with CONFIG_USERSPACE enabled can invoke fuel_gauge_get_props() or fuel_gauge_set_props() with a large len. This first displaces the supervisor stack pointer by an arbitrary attacker-chosen amount — Zephyr does not build with stack-clash probing, so the displacement itself does not fault, and the nested calls made by the verifier then write frames below the privileged stack. If the caller has been granted access to a fuel-gauge device object, the memcpy inside k_usermode_from_copy() additionally writes len * sizeof(union fuel_gauge_prop_val) bytes of fully attacker-controlled data starting well below the stack base. CONFIG_PRIVILEGED_STACK_SIZE defaults to 1024 bytes, so a len of roughly 170 already exhausts it.
The result is an out-of-bounds write in supervisor mode with attacker-controlled length and, on the permitted path, attacker-controlled content — a break out of the user-mode sandbox into kernel memory, leading to kernel code execution or a system crash. A stack guard region does not contain it, because the copy begins below the guard and walks upward, corrupting unprotected memory before the guard is reached. The fix removes the kernel-side copies entirely and validates the caller's arrays in place with K_SYSCALL_MEMORY_ARRAY_READ() / K_SYSCALL_MEMORY_ARRAY_WRITE(), which also handle the len * size multiplication overflow; this is safe because neither fuel_gauge_prop_t nor union fuel_gauge_prop_val contains embedded pointers.