Skip to content

smex: harden ELF parsing against malformed input#10922

Open
lgirdwood wants to merge 5 commits into
thesofproject:mainfrom
lgirdwood:fix-smex
Open

smex: harden ELF parsing against malformed input#10922
lgirdwood wants to merge 5 commits into
thesofproject:mainfrom
lgirdwood:fix-smex

Conversation

@lgirdwood

Copy link
Copy Markdown
Member

Harden smex against malformed/untrusted ELF input (e.g. a build pipeline
running smex on a contributed object):

  • validate the section-header string table index and reject a zero-size
    string section before indexing
  • bound section name offsets against the string-table size
  • clear the freed section-buffer pointer on a read error to avoid a
    double-free in the caller
  • reject an undersized .fw_ready section before casting it to a struct
  • bound the extended-manifest element walk (reject elem_size == 0 or one that
    runs past the section)

lrgirdwo added 5 commits June 11, 2026 14:40
The section name string table was located using a header index without
bounding it against the section count, and was null terminated at size
minus one without checking for a zero-size section. Reject an
out-of-range index and a zero-size string section before use.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
On a read error the section reader freed the output buffer but left the
caller's pointer set, so a caller cleanup path could free it again.
Clear the pointer after freeing.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Section names are used as offsets into the string table; an out-of-range
name offset from a crafted ELF read past the table. Validate every
section name offset against the string-table size after loading the
sections.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
The fw-ready section was cast to a struct and field-read without
checking its size, reading past a short section. Reject a section
smaller than the struct.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
The extended-manifest walk advanced by an element size read from the
section without validating it, so a zero size looped forever and a large
size read past the section. Stop on a zero size or one that would leave
the section.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Copilot AI review requested due to automatic review settings June 15, 2026 14:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Harden smex ELF parsing when handling malformed/untrusted objects by adding bounds checks and safer error handling around string tables, section lookups, and manifest parsing.

Changes:

  • Validate section-header string table index/size and bound section-name offsets against the string table size.
  • Prevent double-free by nulling the caller buffer on elf_read_section() error.
  • Add size/bounds checks for .fw_ready and extended manifest element walking.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
smex/ldc.c Adds defensive size/bounds checks when parsing .fw_ready and extended manifest elements.
smex/elf.c Validates shstrndx/string-table invariants, bounds section name offsets, and hardens error cleanup.

Comment thread smex/ldc.c
Comment on lines +60 to 67
while ((uintptr_t)ext_hdr + sizeof(*ext_hdr) <=
(uintptr_t)buffer + section_size) {
if (ext_hdr->type == EXT_MAN_ELEM_DBG_ABI) {
header->version.abi_version =
((struct ext_man_dbg_abi *)
ext_hdr)->dbg_abi.abi_dbg_version;
break;
}
Comment thread smex/ldc.c
Comment on lines +68 to +75
/* elem_size must advance the cursor and keep the next header
* within the section; otherwise stop instead of looping
* forever (elem_size == 0) or reading past the section
*/
if (ext_hdr->elem_size == 0 ||
(uintptr_t)ext_hdr + ext_hdr->elem_size >
(uintptr_t)buffer + section_size)
break;
Comment thread smex/elf.c
Comment on lines 66 to 67
module->strings = calloc(1, section[hdr->shstrndx].size);
if (!module->strings) {
Comment thread smex/elf.c
Comment on lines +425 to +429
if (hdr->shstrndx >= hdr->shnum) {
fprintf(stderr, "error: invalid shstrndx %u >= shnum %u\n",
hdr->shstrndx, hdr->shnum);
return -EINVAL;
}
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.

3 participants