public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: "Cássio Gabriel" <cassiogabrielcontato@gmail.com>,
	"Peter Ujfalusi" <peter.ujfalusi@linux.intel.com>,
	"Mark Brown" <broonie@kernel.org>,
	"Sasha Levin" <sashal@kernel.org>,
	lgirdwood@gmail.com, yung-chuan.liao@linux.intel.com,
	ranjani.sridharan@linux.intel.com, daniel.baluta@nxp.com,
	perex@perex.cz, tiwai@suse.com,
	sound-open-firmware@alsa-project.org,
	linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH AUTOSEL 6.19-5.10] ASoC: SOF: topology: reject invalid vendor array size in token parser
Date: Mon, 30 Mar 2026 08:38:33 -0400	[thread overview]
Message-ID: <20260330123842.756154-20-sashal@kernel.org> (raw)
In-Reply-To: <20260330123842.756154-1-sashal@kernel.org>

From: Cássio Gabriel <cassiogabrielcontato@gmail.com>

[ Upstream commit 215e5fe75881a7e2425df04aeeed47a903d5cd5d ]

sof_parse_token_sets() accepts array->size values that can be invalid
for a vendor tuple array header. In particular, a zero size does not
advance the parser state and can lead to non-progress parsing on
malformed topology data.

Validate array->size against the minimum header size and reject values
smaller than sizeof(*array) before parsing. This preserves behavior for
valid topologies and hardens malformed-input handling.

Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
Acked-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://patch.msgid.link/20260319-sof-topology-array-size-fix-v1-1-f9191b16b1b7@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

Now I have all the information needed for a comprehensive analysis.

===============================================================
## PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1:** Record: [ASoC: SOF: topology] [reject] [reject invalid
vendor array size in token parser to prevent non-progress parsing]

**Step 1.2:** Record: Tags present:
- Signed-off-by: Cássio Gabriel (author)
- Acked-by: Peter Ujfalusi (confirmed listed SOF maintainer in
  MAINTAINERS)
- Link: patch.msgid.link URL
- Signed-off-by: Mark Brown (ASoC maintainer, merged the patch)
- No Fixes:, Reported-by:, Tested-by:, Cc: stable tags (expected for
  manual review candidates)

**Step 1.3:** Record: Bug: `sof_parse_token_sets()` accepts
`array->size` values that are invalid — specifically, a zero size does
not advance parser state. Symptom: non-progress parsing (infinite loop)
on malformed topology data. Root cause: the validation only checked
`asize < 0`, which cannot catch zero or small positive values.

**Step 1.4:** Record: Yes, this is a real bug fix despite "hardens"
language. The commit fixes a concrete infinite loop scenario where
`asize == 0` causes the parser while-loop to never terminate.

===============================================================
## PHASE 2: DIFF ANALYSIS
===============================================================

**Step 2.1:** Record: 1 file changed (`sound/soc/sof/topology.c`), 1
line modified. Function modified: `sof_parse_token_sets()`.
Classification: single-file, single-line surgical fix.

**Step 2.2:** Record: Before: `if (asize < 0)` — only rejects negative
values. After: `if (asize < sizeof(*array))` — rejects any value smaller
than the vendor array header size. The FIXME comment ("A zero-size array
makes no sense") was already documenting this known deficiency.

**Step 2.3:** Record: Bug category: logic/infinite loop. The while loop
at line 735 uses `array_size -= asize` (line 746) and advances the
pointer via `array = (u8*)array + asize` (line 784). When `asize == 0`:
1. `array_size -= 0` — no change, stays positive
2. `array = array + 0` — pointer doesn't advance
3. The while condition `array_size > 0 && total < count *
   token_instance_num` remains true
4. Result: **infinite loop / soft lockup**

**Step 2.4:** Record: The fix is obviously correct. `struct
snd_soc_tplg_vendor_array` has three `__le32` header fields (`size`,
`type`, `num_elems`) = 12 bytes minimum, plus a flex array union. Any
valid array must be at least `sizeof(*array)` bytes. Note on type
promotion: `asize` is `int`, `sizeof(*)` is `size_t`. A negative `asize`
promotes to a very large unsigned value, so `asize < sizeof(*)` would be
false — but negative `asize` is still caught by the subsequent
`array_size -= asize; if (array_size < 0)` check at line 747, so no
regression.

===============================================================
## PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1:** Record: `git blame` confirms the buggy `if (asize < 0)`
check was introduced in commit `311ce4fe7637d9` ("ASoC: SOF: Add support
for loading topologies") by Liam Girdwood, 2019-04-12. `git describe
--contains` shows this is `v5.2-rc1`. The bug has been present since
**v5.2** — all active stable trees contain it.

**Step 3.2:** Record: No Fixes: tag present. The buggy commit is
`311ce4fe7637d9`.

**Step 3.3:** Record: `git log --oneline -20` shows active development
but no related prerequisite or duplicate fix for this specific issue.

**Step 3.4:** Record: Peter Ujfalusi (Acked-by) is a listed maintainer
for SOF in MAINTAINERS. Mark Brown signed off as ASoC subsystem
maintainer. Strong maintainer endorsement.

**Step 3.5:** Record: No dependencies. The fix changes one condition in
an existing function with no new types, helpers, or APIs needed.

===============================================================
## PHASE 4: MAILING LIST RESEARCH
===============================================================

Record: The patch.msgid.link and lore.kernel.org URLs are blocked by
Anubis bot protection in this environment. However, the patch was Acked
by a listed SOF maintainer (Peter Ujfalusi) and merged by the ASoC
maintainer (Mark Brown), providing strong review signal.

===============================================================
## PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1:** Record: Modified function: `sof_parse_token_sets()`

**Step 5.2:** Record: `sof_parse_token_sets()` is called from:
1. `sof_parse_tokens()` — a wrapper called from ~9 locations throughout
   topology.c (control load, widget parsing, DAI load, link load,
   DSPless widget paths)
2. `sof_parse_pin_binding()` — direct call for pin binding token parsing

This is a heavily-used core parsing function in the SOF topology loader.

**Step 5.3-5.4:** Record: The call chain is: `sof_pcm_probe()` →
`snd_sof_load_topology()` → `snd_soc_tplg_component_load()` → SOF
callbacks (widget_ready, dai_load, link_load, control_load) →
`sof_parse_tokens()` → `sof_parse_token_sets()`. This is triggered
during SOF audio component probe when topology firmware blobs are
loaded.

**Step 5.5:** Record: The **same weak check** (`if (asize < 0)`) exists
in `sof_copy_tuples()` at line 544, with identical loop structure and
pointer advancement at line 610. This sibling function has the same
vulnerability but is NOT fixed by this commit. This means the patch is
not a complete fix across all SOF topology parsing paths, but it does
fix the specific path through `sof_parse_token_sets()`.

===============================================================
## PHASE 6: STABLE TREE ANALYSIS
===============================================================

**Step 6.1:** Record: The buggy code was introduced in v5.2. All active
stable trees (5.4.y, 5.10.y, 5.15.y, 6.1.y, 6.6.y, 6.12.y) contain this
vulnerable code.

**Step 6.2:** Record: Expected clean or trivial backport — the `if
(asize < 0)` line with the FIXME comment hasn't changed since
introduction.

**Step 6.3:** Record: No duplicate or alternative fix found for this
exact issue in git history.

===============================================================
## PHASE 7: SUBSYSTEM CONTEXT
===============================================================

**Step 7.1:** Record: Subsystem: sound/soc/sof (Sound Open Firmware).
Criticality: IMPORTANT — SOF is used on most modern Intel laptops for
audio hardware.

**Step 7.2:** Record: Active subsystem with regular commits.

===============================================================
## PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1:** Record: Affected users: SOF audio hardware users (very
common on Intel-based laptops/desktops).

**Step 8.2:** Record: Trigger: malformed/corrupt SOF topology blob with
`array->size == 0` (or < header size). Topology files are loaded from
firmware path during driver probe. Trigger requires corrupt or
maliciously crafted topology data — uncommon in normal operation but
possible from disk corruption or adversarial input.

**Step 8.3:** Record: Failure mode: infinite loop in kernel context →
soft lockup → system hang during audio driver probe. Severity: HIGH
(system hang, unavailability).

**Step 8.4:** Record:
- **Benefit:** Prevents a real infinite loop / system hang. The FIXME
  comment proves the developer knew this was broken. Low-medium benefit
  (real hang, but only on malformed input).
- **Risk:** Very low. Single condition change; valid topologies always
  have `asize >= sizeof(*array)`. No regression for valid data. Acked by
  subsystem maintainer.
- **Ratio:** Favorable — high confidence in correctness, near-zero
  regression risk, fixes real hang.

===============================================================
## PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: Evidence compilation**

FOR backporting:
- Fixes a concrete infinite loop (system hang) — the FIXME comment
  proves this was a known deficiency
- Single-line, obviously correct fix
- Acked by listed SOF subsystem maintainer (Peter Ujfalusi)
- Merged by ASoC maintainer (Mark Brown)
- Bug present since v5.2 — exists in all active stable trees
- Near-zero regression risk for valid topologies
- `sof_parse_token_sets()` is called from ~10 locations — well-used code
  path

AGAINST backporting:
- Trigger requires malformed topology data (not normal operation)
- No user/syzbot crash report — found by code inspection
- The parallel `sof_copy_tuples()` function retains the same weak check
  (incomplete coverage)
- SOF is important but not core kernel — affects hardware-specific users

**Step 9.2: Stable rules checklist**
1. Obviously correct and tested? **YES** — maintainer acked, trivially
   verifiable from code
2. Fixes a real bug? **YES** — infinite loop on malformed input
   (acknowledged by FIXME comment)
3. Important issue? **YES** — system hang (soft lockup), HIGH severity
4. Small and contained? **YES** — 1 line changed, 1 function, 1 file
5. No new features or APIs? **YES**
6. Can apply to stable trees? **YES** — identical code in all stable
   trees

**Step 9.3:** Record: No exception category — standard bug fix.

**Step 9.4: Decision**

This commit fixes a real, documented infinite loop bug (the original
code even had a FIXME acknowledging the problem). The fix is a single-
line minimum-size validation, acked by the subsystem maintainer, with
near-zero regression risk. While the trigger requires malformed topology
data, a system hang is a serious failure mode — stable kernels should
handle invalid input gracefully without hanging. The incomplete coverage
of the sibling function `sof_copy_tuples()` does not diminish the value
of fixing this specific path. The fix meets all stable kernel criteria.

## Verification

- [Phase 1] Parsed all tags from supplied commit message: Acked-by Peter
  Ujfalusi, Signed-off-by Mark Brown, Link to patch.msgid.link
- [Phase 1] Verified Peter Ujfalusi is listed as maintainer in
  MAINTAINERS under "SOUND - SOUND OPEN FIRMWARE (SOF) DRIVERS"
- [Phase 2] Read `sof_parse_token_sets()` (lines 724-793): confirmed
  while loop at line 735, `array_size -= asize` at line 746, pointer
  advance `(u8*)array + asize` at line 784 — `asize == 0` causes
  infinite loop
- [Phase 2] Verified `struct snd_soc_tplg_vendor_array` in
  `include/uapi/sound/asoc.h` (line 220): three `__le32` fields (`size`,
  `type`, `num_elems`) + flex array union — `sizeof(*array)` is the
  correct minimum header size
- [Phase 2] Verified type safety: `int asize` compared against `size_t
  sizeof(*)` — negative values promote to large unsigned (caught by
  subsequent `array_size < 0` check at line 747)
- [Phase 3] git blame: buggy `if (asize < 0)` line attributed to commit
  `311ce4fe7637d9` (Liam Girdwood, 2019-04-12)
- [Phase 3] git describe: `311ce4fe7637d9` first appeared in `v5.2-rc1`
  — bug present in all active stable trees
- [Phase 3] git log -20: no prerequisites or duplicate fixes found
- [Phase 5] grep callers: `sof_parse_token_sets()` called from
  `sof_parse_tokens()` (~9 call sites) and `sof_parse_pin_binding()` (1
  call site)
- [Phase 5] grep: found same weak `if (asize < 0)` check in sibling
  `sof_copy_tuples()` at line 544, with identical loop/advance pattern
  at line 610 — NOT fixed by this commit
- [Phase 6] Buggy code unchanged since v5.2 — clean backport expected to
  all active stable trees
- [Phase 8] Failure mode: infinite loop in kernel context → soft
  lockup/system hang during topology load. Severity: HIGH
- UNVERIFIED: Lore discussion content (blocked by Anubis protection)
- UNVERIFIED: Whether unprivileged users can trigger topology loading on
  specific distributions
- UNVERIFIED: Exact runtime `sizeof(struct snd_soc_tplg_vendor_array)`
  (struct is `__packed` with flex array — compile-time verification not
  performed)

**YES**

 sound/soc/sof/topology.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
index 9bf8ab610a7ea..8880ac5d8d6ff 100644
--- a/sound/soc/sof/topology.c
+++ b/sound/soc/sof/topology.c
@@ -736,7 +736,7 @@ static int sof_parse_token_sets(struct snd_soc_component *scomp,
 		asize = le32_to_cpu(array->size);
 
 		/* validate asize */
-		if (asize < 0) { /* FIXME: A zero-size array makes no sense */
+		if (asize < sizeof(*array)) {
 			dev_err(scomp->dev, "error: invalid array size 0x%x\n",
 				asize);
 			return -EINVAL;
-- 
2.53.0


  parent reply	other threads:[~2026-03-30 12:39 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-30 12:38 [PATCH AUTOSEL 6.19-6.18] ALSA: hda/realtek: add quirk for Lenovo Yoga 7 2-in-1 16AKP10 Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-6.18] ASoC: amd: acp: add ASUS HN7306EA quirk for legacy SDW machine Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-5.10] btrfs: tracepoints: get correct superblock from dentry in event btrfs_sync_file() Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-6.12] Bluetooth: hci_sync: annotate data-races around hdev->req_status Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-6.12] platform/x86: asus-nb-wmi: add DMI quirk for ASUS ROG Flow Z13-KJP GZ302EAC Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-5.10] srcu: Use irq_work to start GP in tiny SRCU Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-5.10] ALSA: asihpi: avoid write overflow check warning Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-6.1] erofs: add GFP_NOIO in the bio completion if needed Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-6.18] platform/x86: hp-wmi: Add support for Omen 16-wf1xxx (8C76) Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-6.18] ALSA:usb:qcom: add AUXILIARY_BUS to Kconfig dependencies Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-6.12] drm/amdgpu: Handle GPU page faults correctly on non-4K page systems Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-6.1] ALSA: hda/realtek: Add HP ENVY Laptop 13-ba0xxx quirk Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-6.1] ASoC: amd: yc: Add DMI quirk for ASUS EXPERTBOOK BM1403CDA Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-6.18] dmaengine: idxd: Fix lockdep warnings when calling idxd_device_config() Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-6.1] ASoC: amd: yc: Add DMI quirk for Thin A15 B7VF Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-6.1] media: rkvdec: reduce stack usage in rkvdec_init_v4l2_vp9_count_tbl() Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-6.18] btrfs: fix zero size inode with non-zero size after log replay Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-5.10] ALSA: hda/realtek: Add mute LED quirk for HP Pavilion 15-eg0xxx Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-5.10] netfilter: nft_set_pipapo_avx2: don't return non-matching entry on expiry Sasha Levin
2026-03-30 12:38 ` Sasha Levin [this message]
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19] ALSA: hda/realtek - Fixed Speaker Mute LED for HP EliteBoard G1a platform Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-6.18] netfilter: ctnetlink: ensure safe access to master conntrack Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-6.6] RDMA/irdma: Fix double free related to rereg_user_mr Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-5.10] can: mcp251x: add error handling for power enable in open and resume Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-6.18] ALSA: hda/realtek: add HP Laptop 15-fd0xxx mute LED quirk Sasha Levin
2026-03-30 12:38 ` [PATCH AUTOSEL 6.19-6.6] ALSA: hda/realtek: Add quirk for ASUS ROG Flow Z13-KJP GZ302EAC Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260330123842.756154-20-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=broonie@kernel.org \
    --cc=cassiogabrielcontato@gmail.com \
    --cc=daniel.baluta@nxp.com \
    --cc=lgirdwood@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=perex@perex.cz \
    --cc=peter.ujfalusi@linux.intel.com \
    --cc=ranjani.sridharan@linux.intel.com \
    --cc=sound-open-firmware@alsa-project.org \
    --cc=stable@vger.kernel.org \
    --cc=tiwai@suse.com \
    --cc=yung-chuan.liao@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox