Skip to content

topology: harden binary topology decoder against malformed input - #526

Open
HarshRajSinghania wants to merge 1 commit into
alsa-project:masterfrom
HarshRajSinghania:topology-decoder-hardening
Open

HarshRajSinghania wants to merge 1 commit into
alsa-project:masterfrom
HarshRajSinghania:topology-decoder-hardening

Conversation

@HarshRajSinghania

Copy link
Copy Markdown

As discussed over email with Jaroslav, this hardens the binary topology decoder
against malformed / untrusted .tplg input. Three related issues, each confirmed
with AddressSanitizer:

  1. snd_tplg_decode() (src/topology/decoder.c): hdr->size + hdr->payload_size
    is evaluated in 32-bit and can wrap, bypassing the payload bounds check; the
    block decoder is then called with the raw (huge) payload_size, causing an
    out-of-bounds read. Fixed by doing the arithmetic in 64-bit (and the advance
    in size_t).

  2. tplg_decode_dapm_widget() (src/topology/dapm.c): the kcontrol loop reads the
    control header (chdr->type, then mc/ec/bc->size and ->priv.size) before
    the size2 > size check, giving an out-of-bounds read on a truncated payload.
    Fixed by adding size < sizeof(*chdr) / sizeof(*mc|ec|bc) guards and
    computing size2 in size_t.

  3. tplg_decode_dapm_graph() (src/topology/dapm.c): alloca() is called with a
    size derived from the input payload, allowing stack exhaustion on large input.
    Fixed by switching to calloc() / free(), which fails gracefully.

Scope is the debug-oriented decode path only, as you noted. Standalone ASan PoC
harnesses are available if useful.

Signed-off-by: Harsh Raj Singhania raj.harshraut@gmail.com

The binary topology decoder trusts several length/count fields taken
from the input .tplg blob. Three related issues are addressed:

- decoder.c: snd_tplg_decode() computed hdr->size + hdr->payload_size in
  32-bit, which can wrap and bypass the payload bounds check; do the
  arithmetic in 64-bit and compute the advance in size_t.
- dapm.c: tplg_decode_dapm_widget() dereferenced the control header
  before validating the remaining size; add size checks before reading
  the ctl/mixer/enum/bytes headers and compute size2 in size_t.
- dapm.c: tplg_decode_dapm_graph() passed an attacker-influenced size to
  alloca(); use calloc()+free() so oversized input fails gracefully.

These only affect the (debug-oriented) decode path when processing
untrusted or corrupted topology data.

Signed-off-by: Harsh Raj Singhania <raj.harshraut@gmail.com>
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.

1 participant