[PATCH 6.6 046/254] ALSA: pcm: Improve the fix for race of buffer access at PCM OSS layer

Greg Kroah-Hartman
2026-01-28T15:28:53Z

From: Jaroslav Kysela <perex@perex.cz>

commit 47c27c9c9c720bc93fdc69605d0ecd9382e99047 upstream.

Handle the error code from snd_pcm_buffer_access_lock() in
snd_pcm_runtime_buffer_set_silence() function.

Found by Alexandros Panagiotou <apanagio@redhat.com>

Fixes: 93a81ca06577 ("ALSA: pcm: Fix race of buffer access at PCM OSS layer")
Cc: stable@vger.kernel.org # 6.15
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Link: https://patch.msgid.link/20260107213642.332954-1-perex@perex.cz
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/sound/pcm.h | 2 +-
sound/core/oss/pcm_oss.c | 4 +++-
sound/core/pcm_native.c | 9 +++++++--
3 files changed, 11 insertions(+), 4 deletions(-)

--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -1427,7 +1427,7 @@ int snd_pcm_lib_mmap_iomem(struct snd_pc
#define snd_pcm_lib_mmap_iomem NULL
#endif

-void snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime);
+int snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime);

/**
* snd_pcm_limit_isa_dma_size - Get the max size fitting with ISA DMA transfer
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1085,7 +1085,9 @@ static int snd_pcm_oss_change_params_loc
runtime->oss.params = 0;
runtime->oss.prepare = 1;
runtime->oss.buffer_used = 0;
- snd_pcm_runtime_buffer_set_silence(runtime);
+ err = snd_pcm_runtime_buffer_set_silence(runtime);
+ if (err < 0)
+ goto failure;

runtime->oss.period_frames = snd_pcm_alsa_frames(substream, oss_period_size);

--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -705,13 +705,18 @@ static void snd_pcm_buffer_access_unlock
}

/* fill the PCM buffer with the current silence format; called from pcm_oss.c */
-void snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime)
+int snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime)
{
- snd_pcm_buffer_access_lock(runtime);
+ int err;
+
+ err = snd_pcm_buffer_access_lock(runtime);
+ if (err < 0)
+ return err;
if (runtime->dma_area)
snd_pcm_format_set_silence(runtime->format, runtime->dma_area,
bytes_to_samples(runtime, runtime->dma_bytes));
snd_pcm_buffer_access_unlock(runtime);
+ return 0;
}
EXPORT_SYMBOL_GPL(snd_pcm_runtime_buffer_set_silence);