public inbox for linux-sound@vger.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Mark Brown <broonie@kernel.org>, Vinod Koul <vkoul@kernel.org>,
	Takashi Iwai <tiwai@suse.de>, Sasha Levin <sashal@kernel.org>,
	perex@perex.cz, tiwai@suse.com, linux-sound@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH AUTOSEL 7.0-5.10] ALSA: compress: Refuse to update timestamps for unconfigured streams
Date: Mon, 20 Apr 2026 09:17:34 -0400	[thread overview]
Message-ID: <20260420132314.1023554-60-sashal@kernel.org> (raw)
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>

From: Mark Brown <broonie@kernel.org>

[ Upstream commit cf6c18cf83e48986ac40a053d09d3c33624135f6 ]

There are a number of mechanisms, including the userspace accessible
timestamp and buffer availability ioctl()s, which allow us to trigger
a timestamp update on a stream before it has been configured. Since
drivers might rely on stream configuration for reporting of pcm_io_frames,
including potentially doing a division by the number of channels, and
these operations are not meaningful for an unconfigured stream reject
attempts to read timestamps before any configuration is done.

Signed-off-by: Mark Brown <broonie@kernel.org>
Acked-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260401-alsa-unconfigured-tstamp-v1-1-694c2cb5f71d@kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This confirms: `snd_compr_ioctl_avail` calls `snd_compr_calc_avail`
(line 267) which calls `snd_compr_update_tstamp` **before** the state
check at line 275. So even the AVAIL ioctl triggers the `->pointer()`
callback before checking state. The fix in `snd_compr_update_tstamp`
itself properly guards *both* paths (TSTAMP and AVAIL).

Now let me finalize the analysis.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: Subject Line**
- Subsystem: `ALSA: compress`
- Action verb: "Refuse" (defensive/preventive - indicates preventing
  incorrect behavior)
- Summary: Refuse timestamp updates for streams that haven't been
  configured yet.

Record: [ALSA: compress] [Refuse] [Prevent timestamp update on
unconfigured streams]

**Step 1.2: Tags**
- `Signed-off-by: Mark Brown <broonie@kernel.org>` - Author is the ASoC
  subsystem maintainer
- `Acked-by: Vinod Koul <vkoul@kernel.org>` - Vinod Koul is the original
  compress_offload author
- `Signed-off-by: Takashi Iwai <tiwai@suse.de>` - Takashi Iwai is the
  ALSA top-level maintainer
- `Link:` to patch.msgid.link (the submission)

Record: Authored by ASoC subsystem maintainer, Acked by compress_offload
author, merged by ALSA maintainer. Strong review pedigree.

**Step 1.3: Commit Body**
The commit describes: userspace-accessible timestamp and buffer
availability ioctls can trigger a timestamp update on a stream before it
has been configured. Drivers might rely on stream configuration for
reporting `pcm_io_frames`, including "potentially doing a division by
the number of channels." Since these operations are not meaningful for
unconfigured streams, reject attempts to read timestamps before
configuration.

Record: Bug = calling driver `->pointer()` callback before `set_params`
has been called. Symptom = potential divide-by-zero in drivers (number
of channels = 0 before configuration). Root cause = missing state
validation in `snd_compr_update_tstamp()`.

**Step 1.4: Hidden Bug Fix?**
This is explicitly a defensive fix preventing a divide-by-zero crash.
The "Refuse" language hides what is actually a crash prevention fix.

Record: YES, this is a hidden bug fix. The commit message explicitly
says "doing a division by the number of channels" which is the crash
mechanism.

## PHASE 2: DIFF ANALYSIS

**Step 2.1: Inventory**
- Single file: `sound/core/compress_offload.c`
- Lines added: ~7 (switch statement checking SNDRV_PCM_STATE_OPEN)
- Lines removed: 0
- Function modified: `snd_compr_update_tstamp()`
- Classification: Single-file surgical fix

**Step 2.2: Code Flow Change**
Before: `snd_compr_update_tstamp()` immediately calls
`stream->ops->pointer()` with no state validation.
After: A switch statement checks if `stream->runtime->state ==
SNDRV_PCM_STATE_OPEN` (pre-configuration state) and returns `-EBADFD` if
so, preventing the `->pointer()` call.

**Step 2.3: Bug Mechanism**
Category: Divide-by-zero / uninitialized state access. When a compress
offload stream is just opened (state = OPEN), driver parameters
(channels, sample_container_bytes) are zero. Calling `->pointer()` in
this state causes drivers like SOF's `sof_compr_pointer()` to execute
`div_u64(..., sstream->channels * sstream->sample_container_bytes)`
which divides by zero.

**Step 2.4: Fix Quality**
- Obviously correct: The state check pattern is used extensively
  throughout this same file (lines 276, 391, 446, 652, 846, 946, 998)
- Minimal: 7 lines added
- No regression risk: Returning -EBADFD for OPEN state is the standard
  pattern used by all other ioctls
- The caller `snd_compr_calc_avail` already has comment "Still need to
  return avail even if tstamp can't be filled in" showing it handles the
  error

## PHASE 3: GIT HISTORY

**Step 3.1: Blame**
- `snd_compr_update_tstamp()` was introduced by commit b21c60a4edd22e
  (2011, v3.3-era) by Vinod Koul as part of the original
  compress_offload support
- The bug has existed since the very beginning (~2011)

**Step 3.2: Fixes tag**
- No Fixes: tag present (expected for autosel candidates)

**Step 3.3: File history**
- Recent changes to the file: 64-bit timestamp infrastructure
  (2c92e2fbe9e22c, Sept 2025) made the issue more visible since it
  changed the pointer callback signature, but the underlying bug
  predates that

**Step 3.4: Author**
- Mark Brown (`broonie@kernel.org`) is the ASoC subsystem maintainer -
  one of the most trusted kernel developers

**Step 3.5: Dependencies**
- This fix applies independently. It only adds a state check using
  existing infrastructure (`SNDRV_PCM_STATE_OPEN`).
- NOTE: In older stable trees (pre-6.12ish), the function signature may
  differ (uses `snd_compr_tstamp` instead of `snd_compr_tstamp64`), but
  the state check logic is identical and would need only trivial
  adaptation.

## PHASE 4: MAILING LIST

Lore was blocked by Anubis anti-bot protection. However:
- The patch was v1 (no revisions needed, indicating it was clean from
  the start)
- It was Acked by the compress_offload author Vinod Koul
- Merged directly by ALSA maintainer Takashi Iwai

Record: Could not fetch lore discussion. Strong review indicators from
tags.

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: Functions modified**
- `snd_compr_update_tstamp()` - the internal timestamp update helper

**Step 5.2: Callers**
- `snd_compr_calc_avail()` (line 209) - called from AVAIL/AVAIL64 ioctls
- `snd_compr_tstamp()` (line 760) - called from TSTAMP/TSTAMP64 ioctls
- Both paths are directly reachable from userspace via ioctl

**Step 5.3-5.4: Call chain**
`open() → ioctl(SNDRV_COMPRESS_TSTAMP) → snd_compr_tstamp() →
snd_compr_update_tstamp() → stream->ops->pointer()` - This is directly
triggerable by any user with access to the compress device.

**Step 5.5: Similar patterns**
- Confirmed: `sof_compr_pointer()` does `div_u64(..., sstream->channels
  * sstream->sample_container_bytes)` at line 384-385
- `sst_cdev_tstamp()` does `div_u64(fw_tstamp.hardware_counter,
  stream->num_ch * ...)` at line 348-349
- Both would divide by zero if called before set_params

## PHASE 6: STABLE TREE ANALYSIS

**Step 6.1: Code exists in stable trees**
- The buggy function `snd_compr_update_tstamp()` has existed since 2011
  (v3.3)
- Present in ALL active stable trees
- NOTE: The 64-bit tstamp infrastructure is only in v6.12+. Older trees
  use `snd_compr_tstamp` struct. The fix concept applies to all, but the
  exact patch applies cleanly only to v7.0 and trees with the 64-bit
  tstamp change.

**Step 6.2: Backport complications**
- For v7.0: Applies cleanly (verified function matches exactly)
- For older trees: Needs minor adaptation (different struct type in
  signature)

**Step 6.3: Related fixes**
- No similar state check has been applied to `snd_compr_update_tstamp`
  before

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: Subsystem**
- `sound/core/` - ALSA core, IMPORTANT criticality
- Compress offload is used by mobile/embedded platforms (Qualcomm, Intel
  Atom, SOF)

**Step 7.2: Activity**
- Active subsystem with recent work (64-bit tstamp infrastructure added
  in 2025)

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: Who is affected**
- Users of ALSA compressed audio (primarily mobile/embedded, Android,
  Intel Atom, SOF platforms)

**Step 8.2: Trigger conditions**
- Trivially triggerable: open compress device, call TSTAMP or AVAIL
  ioctl before SET_PARAMS
- Can be triggered by unprivileged user with access to the audio device
- No special timing required - completely deterministic

**Step 8.3: Failure severity**
- Divide-by-zero → kernel oops/crash → **CRITICAL**

**Step 8.4: Risk-benefit**
- BENEFIT: Very high - prevents deterministic kernel crash from
  userspace
- RISK: Very low - 7 lines, uses established pattern, authored by ASoC
  maintainer, acked by compress_offload author

## PHASE 9: FINAL SYNTHESIS

**Evidence FOR:**
1. Fixes a divide-by-zero crash triggerable from userspace (CRITICAL)
2. Extremely small and surgical fix (7 lines)
3. Uses an existing, well-established pattern (same check at 6+ other
   locations in the file)
4. Authored by ASoC subsystem maintainer Mark Brown
5. Acked by compress_offload original author Vinod Koul
6. Bug exists since 2011 - affects all stable trees
7. Multiple drivers have the vulnerable division (SOF, Intel Atom)

**Evidence AGAINST:**
1. Needs minor adaptation for trees without 64-bit tstamp (pre-6.12ish)

**Stable rules checklist:**
1. Obviously correct? YES - uses identical pattern to 6+ other ioctls in
   same file
2. Fixes a real bug? YES - divide-by-zero crash
3. Important issue? YES - kernel crash triggerable from userspace
4. Small and contained? YES - 7 lines, single function
5. No new features/APIs? Correct - purely defensive check
6. Applies to stable? YES for 7.0 (clean apply); needs minor rework for
   older trees

## Verification

- [Phase 1] Parsed tags: Signed-off-by Mark Brown (ASoC maintainer),
  Acked-by Vinod Koul (compress_offload author), Signed-off-by Takashi
  Iwai (ALSA maintainer)
- [Phase 2] Diff analysis: 7 lines added in `snd_compr_update_tstamp()`,
  adds state check for SNDRV_PCM_STATE_OPEN
- [Phase 3] git blame: `snd_compr_update_tstamp()` introduced in commit
  b21c60a4edd22e (2011), present in all stable trees
- [Phase 3] git show b21c60a4edd22e: confirmed original compress_offload
  commit
- [Phase 3] git merge-base: confirmed 64-bit tstamp infrastructure
  (2c92e2fbe9e22c) is ancestor of v7.0
- [Phase 4] Lore blocked by Anubis; relied on tag analysis for review
  evidence
- [Phase 5] Grep callers: `snd_compr_update_tstamp` called from lines
  209 and 760, both ioctl-reachable
- [Phase 5] Verified SOF driver `sof_compr_pointer()` does `div_u64(...,
  sstream->channels * sstream->sample_container_bytes)` at line 384-385
- [Phase 5] Verified Intel Atom `sst_cdev_tstamp()` does `div_u64(...,
  stream->num_ch * ...)` at line 348-349
- [Phase 5] Verified `snd_compr_set_params()` sets channels (line 256 in
  sof compress.c), confirming channels=0 before set_params
- [Phase 6] git show v7.0:compress_offload.c: function matches current
  HEAD exactly, clean apply confirmed
- [Phase 6] Existing divide-by-zero protection commit 678e2b44c8e3fec
  (2018) validates this class of bug is real
- [Phase 7] Identified `snd_compr_ioctl_avail` line 267 calls
  update_tstamp BEFORE its own state check at line 275, confirming both
  AVAIL and TSTAMP paths are vulnerable
- [Phase 8] Failure mode: divide-by-zero → kernel oops, severity
  CRITICAL, trivially triggerable from userspace

This is a textbook stable backport: a small, surgical fix preventing a
deterministic kernel crash (divide-by-zero) that is trivially
triggerable from userspace via ioctl. Authored and reviewed by the top
three relevant maintainers.

**YES**

 sound/core/compress_offload.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index fdba6e4b25fdc..67b3b1a3b5261 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -192,6 +192,14 @@ static int snd_compr_update_tstamp(struct snd_compr_stream *stream,
 {
 	if (!stream->ops->pointer)
 		return -ENOTSUPP;
+
+	switch (stream->runtime->state) {
+	case SNDRV_PCM_STATE_OPEN:
+		return -EBADFD;
+	default:
+		break;
+	}
+
 	stream->ops->pointer(stream, tstamp);
 	pr_debug("dsp consumed till %u total %llu bytes\n", tstamp->byte_offset,
 		 tstamp->copied_total);
-- 
2.53.0


  parent reply	other threads:[~2026-04-20 13:24 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-20 13:16 [PATCH AUTOSEL 7.0-5.10] ASoC: tas2552: Allow audio enable GPIO to sleep Sasha Levin
2026-04-20 13:16 ` [PATCH AUTOSEL 7.0-5.10] ASoC: Intel: bytcr_rt5651: Fix MCLK leak on platform_clock_control error Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 7.0-6.18] ALSA: usb-audio: Add iface reset and delay quirk for HUAWEI USB-C HEADSET Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 6.18] ALSA: hda/realtek: Add quirk for Lenovo Yoga Pro 7 14IMH9 Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 7.0-5.10] ALSA: aoa/tas: Fix OF node leak on probe failure Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 7.0-5.10] ASoC: ti: davinci-mcasp: Add system suspend/resume support Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 6.18] ALSA: asihpi: avoid write overflow check warning Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 7.0-5.10] ASoC: rt5640: Handle 0Hz sysclk during stream shutdown Sasha Levin
2026-04-20 13:17 ` Sasha Levin [this message]
2026-04-20 13:17 ` [PATCH AUTOSEL 7.0-5.10] ASoC: Intel: cht_bsw_rt5672: Fix MCLK leak on platform_clock_control error Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 7.0-5.10] ASoC: codecs: wcd-clsh: Always update buck/flyback on transitions on transitions Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 6.18] ALSA:usb:qcom: add AUXILIARY_BUS to Kconfig dependencies Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 6.18] ASoC: SDCA: Fix overwritten var within for loop Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 7.0-6.19] ASoC: sdw_utils: Add CS42L43B codec info Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 7.0-6.1] ASoC: mxs-sgtl5000: disable MCLK on error paths of mxs_sgtl5000_probe() Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 6.18] ASoC: amd: acp: update DMI quirk and add ACP DMIC for Lenovo platforms Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 6.18] ALSA: hda/realtek: Add HP ENVY Laptop 13-ba0xxx quirk Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 6.18] ALSA: usb-audio: Fix quirk flags for NeuralDSP Quad Cortex Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 6.18] ASoC: amd: yc: Add DMI quirk for ASUS EXPERTBOOK BM1403CDA Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 6.18] ALSA: hda/realtek: Add quirk for Lenovo Yoga Slim 7 14AKP10 Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 6.18] ALSA: hda/realtek: Add quirk for Lenovo Yoga Pro 7 14IAH10 Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 6.18] ASoC: stm32_sai: fix incorrect BCLK polarity for DSP_A/B, LEFT_J Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 6.18] ASoC: amd: yc: Add DMI quirk for Thin A15 B7VF Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 7.0-6.19] ALSA: hda/realtek: Add support for HP Laptops Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 7.0-6.12] ALSA: hda/realtek: Add quirk for Acer PT316-51S headset mic Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 7.0-6.18] ALSA: usb-audio: add Studio 1824 support Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 7.0-6.1] ASoC: amd: yc: Add MSI Vector A16 HX A8WHG to quirk table Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 6.18] ALSA: hda/realtek: Add quirk for Samsung Book2 Pro 360 (NP950QED) Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 6.18] ALSA: hda/realtek: Add mute LED quirk for HP Pavilion 15-eg0xxx Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 6.18] ASoC: SOF: topology: reject invalid vendor array size in token parser Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 7.0-6.12] ALSA: pcm: Use pcm_lib_apply_appl_ptr() in x32 sync_ptr Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 6.18] ASoC: soc-core: call missing INIT_LIST_HEAD() for card_aux_list Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 7.0-5.10] ASoC: Intel: bytcr_rt5640: Fix MCLK leak on platform_clock_control error Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 7.0-6.6] ALSA: hda/realtek: Add quirk for HP Spectre x360 14-ea Sasha Levin
2026-04-20 13:22 ` [PATCH AUTOSEL 7.0-6.18] ALSA: usb-audio: Add quirk flags for Feaulle Rainbow Sasha Levin
2026-04-20 13:22 ` [PATCH AUTOSEL 6.18] ALSA: hda/realtek: add HP Laptop 15-fd0xxx mute LED quirk Sasha Levin
2026-04-20 13:22 ` [PATCH AUTOSEL 6.18] 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=20260420132314.1023554-60-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=broonie@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=perex@perex.cz \
    --cc=stable@vger.kernel.org \
    --cc=tiwai@suse.com \
    --cc=tiwai@suse.de \
    --cc=vkoul@kernel.org \
    /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