Skip to content

tools: rimage: bound pin and mod_cfg writes to their allocations - #11288

Open
Shrusti-pk wants to merge 1 commit into
thesofproject:mainfrom
Shrusti-pk:rimage-toml-array-bound
Open

Shrusti-pk wants to merge 1 commit into
thesofproject:mainfrom
Shrusti-pk:rimage-toml-array-bound

Conversation

@Shrusti-pk

Copy link
Copy Markdown

Two heap overflows in the rimage manifest parser, both because the write loop follows the toml array length while the destination was sized from the divided count:

  • parse_pin allocates nelem / 6 pin descriptors, then loops until an element is missing, so a pin array whose length is not a multiple of 6 still has a valid element at index 6 * (nelem / 6) and writes one descriptor past the calloc
  • parse_mod_config writes one int per array element into mod_cfg, which parse_module sized for entry_count * MAX_MODULES configs, and the mod_cfg_count > tmp_cfg_count guard only runs after the loop has already overrun it with config-supplied values

Both arrays are now checked before anything is written, which is what the existing post-loop "only %u parsed for %u cfgs" error was already trying to catch. Verified under ASan: a pin array of 7 is a 4-byte write 0 bytes after the 24-byte region, and a mod_cfg of 363 ints is a write 0 bytes after the 1408-byte region; both are clean rejections after this. Every pin array in tree is a multiple of 6 and every mod_cfg a multiple of 11, so valid configurations keep their behaviour, and the verbose config dump for 32 real module entries is identical before and after.

parse_pin() allocates toml_array_nelem(arr) / 6 pin descriptors and then
loops with "for (i = 0; ; i += 6, j++)", breaking only once toml_raw_at()
returns NULL. A pin array whose length is not a multiple of 6 still has a
valid element at index 6 * (nelem / 6), so the loop runs once more and
writes pin_desc[nelem / 6], one descriptor past the end of the calloc.

parse_mod_config() writes one int per array element into modules->mod_cfg,
which parse_module() sized for entry_count * MAX_MODULES configurations of
11 uint32 each. The mod_cfg_count > tmp_cfg_count guard in parse_module()
only runs after parse_mod_config() has returned, so a mod_cfg array
declaring more configurations than the remaining capacity overruns the
allocation with config-supplied values first.

Validate both arrays before writing anything: reject a pin length that is
not a multiple of 6, and a mod_cfg length that is not a multiple of 11 or
that exceeds the mod_cfg entries still free. Bound the pin loop with the
entry count it already computed.

Every pin array in tree is a multiple of 6 and every mod_cfg a multiple of
11, so valid configurations keep their behaviour.

Signed-off-by: Shrushti P K <shrusthi@labs.digiscrypt.com>
@sofci

sofci commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator

Can one of the admins verify this patch?

reply test this please to run this test once

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants