ALSA: pcm: Improve the fix for race of buffer access at PCM OSS layer

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: 93a81ca065 ("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>
This commit is contained in:
Jaroslav Kysela 2026-01-07 22:36:42 +01:00 committed by Takashi Iwai
parent 9ed7a28225
commit 47c27c9c9c
3 changed files with 11 additions and 4 deletions

View 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

View 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);

View 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);