All of lore.kernel.org
 help / color / mirror / Atom feed
From: Omer Cohen <nevergfx1@gmail.com>
To: tiwai@suse.de, broonie@kernel.org
Cc: alsa-devel@alsa-project.org, security@kernel.org,
	Omer Cohen <nevergfx1@gmail.com>,
	stable@vger.kernel.org
Subject: [PATCH 1/6] ALSA: compress: remove illegal state mutation in poll()
Date: Fri, 26 Jun 2026 16:47:04 +0300	[thread overview]
Message-ID: <20260626134709.27883-2-nevergfx1@gmail.com> (raw)
In-Reply-To: <20260626134709.27883-1-nevergfx1@gmail.com>

snd_compr_poll() transitions runtime->state from DRAINING to SETUP
when it observes a drained stream.  This write is unsynchronized with
snd_compress_wait_for_drain(), which reads runtime->state in its
wait_event condition after the device mutex is dropped.

KCSAN flags this on an arm64 system:

  BUG: KCSAN: data-race in snd_compr_poll / snd_compress_wait_for_drain

  write to 0xffff0000c75c8200 of 4 bytes by task 282 on cpu 3:
   snd_compr_poll+0x29c/0x2c8

  read to 0xffff0000c75c8200 of 4 bytes by task 279 on cpu 1:
   snd_compress_wait_for_drain+0xa4/0x270

  value changed: 0x00000005 -> 0x00000001

poll() is a query operation and should not mutate stream state.  The
DRAINING to SETUP transition is already performed by drivers via
snd_compr_drain_notify() when drain actually completes.  The redundant
transition in poll() has been present since the initial compress
offload implementation but only manifests when poll() and drain run
concurrently from different threads.

Remove the state mutation from poll().  When the stream is DRAINING,
report it as ready so userspace can proceed without altering state.

Reproducer (requires any compress offload device, CONFIG_KCSAN=y,
CONFIG_KCSAN_STRICT=y):

  /* 4 threads on the same compress fd, ~2000 iterations to trigger */
  static int compr_fd;

  void *poll_thread(void *arg) {
      struct pollfd pfd = { .fd = compr_fd, .events = POLLOUT };
      while (!stop) poll(&pfd, 1, 10);
      return NULL;
  }
  void *drain_thread(void *arg) {
      while (!stop) ioctl(compr_fd, SNDRV_COMPRESS_DRAIN);
      return NULL;
  }
  void *stop_thread(void *arg) {
      while (!stop) { usleep(500); ioctl(compr_fd, SNDRV_COMPRESS_STOP); }
      return NULL;
  }
  /* main: open compress dev, SET_PARAMS, write data, START,
   * then spawn all 3 threads + repeat setup in a loop.
   * KCSAN fires within seconds. */

  Full reproducer source available on request.

Fixes: b21c60a4edd2 ("ALSA: core: add support for compress_offload")
Cc: stable@vger.kernel.org
Reported-by: Omer Cohen <nevergfx1@gmail.com>
Signed-off-by: Omer Cohen <nevergfx1@gmail.com>
---
 sound/core/compress_offload.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index fd63d219bf86..XXXXXXXXXXXX 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -478,11 +478,8 @@ static __poll_t snd_compr_poll(struct file *f, poll_table *wait)
 	/* check if we have at least one fragment to fill */
 	switch (runtime->state) {
 	case SNDRV_PCM_STATE_DRAINING:
-		/* stream has been woken up after drain is complete
-		 * draining done so set stream state to stopped
-		 */
+		/* drain completed or completing, report ready */
 		retval = snd_compr_get_poll(stream);
-		runtime->state = SNDRV_PCM_STATE_SETUP;
 		break;
 	case SNDRV_PCM_STATE_RUNNING:
 	case SNDRV_PCM_STATE_PREPARED:
--
2.43.0

  reply	other threads:[~2026-06-30 11:56 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-26 13:47 [PATCH 0/6] ALSA: sound/core: fix multiple data races and bugs Omer Cohen
2026-06-26 13:47 ` Omer Cohen [this message]
2026-06-26 13:47 ` [PATCH 2/6] ALSA: compress: fix buffer leak on set_params driver failure Omer Cohen
2026-06-26 13:47 ` [PATCH 3/6] ALSA: timer: fix lockless tu->tread read in snd_timer_user_read() Omer Cohen
2026-06-26 13:47 ` [PATCH 4/6] ALSA: timer: copy queue entries to local buffer before copy_to_user Omer Cohen
2026-06-26 13:47 ` [PATCH 5/6] ALSA: pcm: use locked state read in snd_pcm_drop() Omer Cohen
2026-06-26 13:47 ` [PATCH 6/6] ALSA: rawmidi: propagate resize_runtime_buffer() error in input_params Omer Cohen
2026-07-02  7:30 ` [PATCH 0/6] ALSA: sound/core: fix multiple data races and bugs Takashi Iwai
2026-07-02  7:41   ` Omer Cohen

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=20260626134709.27883-2-nevergfx1@gmail.com \
    --to=nevergfx1@gmail.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=security@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tiwai@suse.de \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.