The Linkable Loadable Extensions (llext) subsystem mis-handles PLT/RELA relocation entries when linking a relocatable (partially-linked) ELF extension. In llext_link_plt() (subsys/llext/llext_link.c), the relocatable branch (tgt != NULL, the path used for Xtensa relocatable objects) computed the patch address as ext->mem[LLEXT_MEM_TEXT] - text.sh_offset + rela.r_offset + tgt->sh_offset and then performed the relocation write there without validating rela.r_offset. Its sibling shared/dynamic branch already rejected out-of-range offsets via llext_file_offset().
rela.r_offset is read directly from the ELF's RELA table, so a crafted entry with an offset larger than the target section makes the write land arbitrarily far outside the extension's text buffer. The result is an attacker-influenced out-of-bounds write (the location via r_offset, the written value being the resolved symbol address) performed in supervisor context at link time, before any extension code runs.
The path is reached from llext_load() whenever an application loads an attacker-influenced ELF extension on Xtensa with writable storage; llext is documented to accept extensions of untrusted origin. Impact is supervisor-context memory corruption (integrity and availability loss, and a sandbox-boundary escape for user-mode extensions). Exploitation is gated by the Xtensa relocatable PLT path and writable storage, and turning the out-of-range write into a useful primitive is non-trivial.
The fix adds a bound check rejecting any RELA entry whose r_offset >= tgt->sh_size, mirroring the existing validation in the shared branch.
{
"cna_assigner": "zephyr",
"cwe_ids": [
"CWE-787"
],
"osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/12xxx/CVE-2026-12235.json"
}"https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-12235.json"
[
{
"deprecated": false,
"digest": {
"function_hash": "113292722997919077728948479242605722341",
"length": 2870
},
"id": "CVE-2026-12235-6d587d19",
"signature_type": "Function",
"signature_version": "v1",
"source": "https://github.com/zephyrproject-rtos/zephyr/commit/106540afbd22087ad40b90f53fb22657754a719e",
"target": {
"file": "subsys/llext/llext_link.c",
"function": "llext_link_plt"
}
},
{
"deprecated": false,
"digest": {
"line_hashes": [
"104093657600737211811312920324316877613",
"275060079479860757930027242392016029972",
"20577632894537155701062780061802078652",
"300967193320644165986352140264335323607",
"227798336776120057627615307105696390120",
"54776370691421580850233073303381474240",
"220709915079258230827793601824159739993",
"184792604639254598134778438655925917921",
"201561984211959582624779422042619552289",
"170023150180655828589399639296434243355",
"232988519097173838809793431136139896846",
"158174359383958421328426391981069252407",
"273617652213560345199276186379607160131",
"220929425614529506416643782156558507188",
"185943400793034324873219271403908770762",
"92313287457520890740747739921129787936",
"282113568989849375466202570209284531036",
"141855325836174787780417854245375785386",
"296798628537328967344166023364600449436",
"107793931771149914453017227735289949460"
],
"threshold": 0.9
},
"id": "CVE-2026-12235-e3e69016",
"signature_type": "Line",
"signature_version": "v1",
"source": "https://github.com/zephyrproject-rtos/zephyr/commit/106540afbd22087ad40b90f53fb22657754a719e",
"target": {
"file": "subsys/llext/llext_link.c"
}
}
]
"2026-08-28T14:32:51Z"