GHSA-372w-c338-xj8p: GUIX binary resource loader: a theme id past the resource’s theme count causes a heap out-of-bounds write
GHSA ID |
|
|---|---|
CVE ID |
CVE‑2026‑102729 |
Severity |
Medium |
CVSS score |
6.5 ( |
CWE |
|
Published |
2026‑10‑02 |
Last updated |
2026‑10‑02 |
Description
Summary
gx_binres_theme_load() sizes its theme buffer for the theme it was asked for, and allocates it even when the resource holds no theme with that id. A theme id at or past the theme count declared by the resource gets a buffer of zero bytes. The load pass then walks past the end of the theme table, takes whatever follows as a theme header, and writes a GX_THEME and its tables into that zero-byte buffer.
Details
_gx_binres_theme_buffer_allocate() walks the theme headers up to gx_resource_header_theme_count, adding up the space the requested theme needs when it finds it. When no theme matches, the size stays at zero and the function still calls _gx_system_memory_allocator(0).
The load loop in _gx_binres_theme_load() has no bound of its own. It is an unterminated for that stops only when the index reaches the requested theme id, so for an id past the last theme it always gets there, reading the bytes beyond the theme table as a theme header. It then stores the theme record, and the color, font and pixelmap tables that header describes, starting at the zero-byte buffer.
The theme id comes from the application, but the theme count comes from the resource. A theme file that declares fewer themes than the application asks for is enough, with no other malformation.
Impact
A heap out-of-bounds write whose extent and content follow the bytes after the theme table, which the resource controls.
The threat model is an untrusted resource file: a firmware asset from an unverified source, a downloaded or user-supplied theme, or an OTA-delivered resource bundle.
Affected configurations
An application that loads a binary resource it does not control, built with a memory allocator that returns a usable pointer for a request of zero bytes, as malloc() does. The ThreadX byte pool refuses such a request, so an application that allocates GUIX memory from a byte pool receives GX_SYSTEM_MEMORY_ERROR and never reaches the write.
Every GUIX release up to and including 6.5.1.202602a is affected. The sizing pass and the unbounded load loop are present in every release tag from v6.0_rel onwards.
Severity
CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:L/I:H/A:H, 6.5, Medium.
Attack complexity is high because the write depends on a condition the attacker does not control: the allocator must return a usable pointer for a zero-byte request, which the ThreadX byte pool does not. User interaction is required because the application must load the resource for anything to happen.
Patches
Fixed in GUIX 6.5.2.202603. The sizing pass refuses a theme id at or past the declared theme count with GX_INVALID_VALUE, before anything is allocated. A negative id converts to a count no resource can declare, so the same test refuses it.
The regression test in validation_guix_binres_ext_api_no_output walks theme ids against a two-theme resource until one is refused, and asserts that refusal arrives at the third id with GX_INVALID_VALUE, that no theme pointer is returned, and that no allocation is left outstanding. A separate assertion covers the negative id.