tplg: reject zero-size arrays and undersized private data#10938
tplg: reject zero-size arrays and undersized private data#10938lgirdwood wants to merge 2 commits into
Conversation
A vendor array with zero size never advanced the parse cursor, looping forever on a malformed topology. Reject a zero-size array. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
The private-data size had the ABI header length subtracted without checking it was at least that large, underflowing the computed size. Reject private data smaller than the header in both append paths. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Improves robustness of the host-side topology parser against crafted .tplg inputs by preventing an infinite loop on zero-length arrays and avoiding underflow when computing process-widget private data sizes.
Changes:
- Reject zero-size vendor arrays to prevent the parse cursor from never advancing.
- Reject process private data smaller than the ABI header before subtracting header size.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| tools/tplg_parser/process.c | Adds size validation to prevent underflow when subtracting ABI header from private data. |
| tools/tplg_parser/object.c | Adds validation to reject zero-size arrays and avoid infinite parsing loops. |
| if (bytes_ctl->priv.size < sizeof(struct sof_abi_hdr)) { | ||
| fprintf(stderr, "error: process priv data too small: %u\n", | ||
| bytes_ctl->priv.size); | ||
| return -EINVAL; | ||
| } |
There was a problem hiding this comment.
priv.size is __le32 (see struct snd_soc_tplg_private in sound/asoc.h), i.e. a 32-bit value, so %u is correct here — it's not a size_t.
| if (bytes_ctl->priv.size < sizeof(struct sof_abi_hdr)) { | ||
| fprintf(stderr, "error: process priv data too small: %u\n", | ||
| bytes_ctl->priv.size); | ||
| return -EINVAL; | ||
| } |
There was a problem hiding this comment.
Same — priv.size is __le32 (32-bit), so %u matches; no %zu needed.
| if (array->size == 0) { | ||
| fprintf(stderr, "error: load %s zero-size array\n", name); | ||
| return -EINVAL; | ||
| } |
There was a problem hiding this comment.
%s is name (the object/widget type being loaded), matching the other error messages in this same function (e.g. "error: load %s array size mismatch"). Kept it consistent with the existing logging style here.
|
Not tested by internal CI |
Two robustness fixes in the host-side topology parser (testbench/plugin)
against crafted .tplg input:
cursor and loops forever
subtracting, which otherwise underflows the remaining-size computation