]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ALSA: pcm: Improve the fix for race of buffer access at PCM OSS layer
authorJaroslav Kysela <perex@perex.cz>
Wed, 7 Jan 2026 21:36:42 +0000 (22:36 +0100)
committerTakashi Iwai <tiwai@suse.de>
Thu, 8 Jan 2026 07:07:54 +0000 (08:07 +0100)
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>
include/sound/pcm.h
sound/core/oss/pcm_oss.c
sound/core/pcm_native.c

index 58fd6e84f9613fd2e8a1e09500ff3a0e6abe8201..a7860c047503a84ef035d7735ce2a90af7a2e720 100644 (file)
@@ -1402,7 +1402,7 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_s
 #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
index a82dd155e1d3a630a33d828c847f54fc3e925d31..b12df5b5ddfc17b8023199e03c2fa3b4bbf899cd 100644 (file)
@@ -1074,7 +1074,9 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
        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);
 
index 68bee40c9adafd9bbb079c058ecf80d14f8885c7..932a9bf98cbc096d698dd8839607ef8828b07827 100644 (file)
@@ -730,13 +730,18 @@ static void snd_pcm_buffer_access_unlock(struct snd_pcm_runtime *runtime)
 }
 
 /* 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);