| From acac7b5e07349a9d10d78873afb4b93cd1dc721f Mon Sep 17 00:00:00 2001 |
| From: Takashi Iwai <tiwai@suse.de> |
| Date: Fri, 28 Aug 2026 13:55:39 +0200 |
| Subject: ALSA: pcm: Fix race between non-atomic ops and trigger-start |
| |
| From: Takashi Iwai <tiwai@suse.de> |
| |
| commit acac7b5e07349a9d10d78873afb4b93cd1dc721f upstream. |
| |
| We protect the races of the concurrent state transitions between |
| atomic PCM ops, but the checks between the non-atomic ops (hw_params, |
| hw_free and prepare) and the atomic ops aren't perfect; there is a |
| check of the conflicting PCM state at the beginning of hw_params & co, |
| but the atomic PCM ops can be still issued during the non-atomic PCM |
| operations. An example such scenario is that a thread A re-issues the |
| PREPARE or HW_PARAMS for the already prepared stream, while another |
| thread B triggers the PCM start in the middle of the prepare |
| operation. Although this usually doesn't lead to much serious issues, |
| it can give some inconsistency as reported by syzkaller (such as |
| ODEBUG warning). |
| |
| There are various atomic PCM ops, and basically the only problem is |
| the PCM start as it operates from the PREPARED state. Other trigger |
| commands (stop, etc) are for the running or the other special state, |
| hence they are filtered as pre-condition. |
| |
| This patch is for preventing the PCM trigger-start during the non- |
| atomic operations in order to address the problems above. |
| Fortunately, the hw_params, hw_free and prepare operations call |
| snd_pcm_buffer_access_lock(), and this can be used for checking the |
| concurrent operations at the PCM trigger -- which sets the |
| runtime->buffer_accessing to a negative (if possible), so the PCM |
| trigger just needs to check the runtime->buffer_accessing value; if |
| it's negative, it means the concurrent non-atomic PCM ops is running. |
| |
| Reported-by: syzbot+225231fce6755d40d078@syzkaller.appspotmail.com |
| Closes: https://lore.kernel.org/6a8f0de8.1d9ded08.62e62.00b5.GAE@google.com |
| Cc: <stable@vger.kernel.org> |
| Link: https://patch.msgid.link/20260828115542.3999-1-tiwai@suse.de |
| Signed-off-by: Takashi Iwai <tiwai@suse.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| sound/core/pcm_native.c | 2 ++ |
| 1 file changed, 2 insertions(+) |
| |
| --- a/sound/core/pcm_native.c |
| +++ b/sound/core/pcm_native.c |
| @@ -1411,6 +1411,8 @@ static int snd_pcm_pre_start(struct snd_ |
| struct snd_pcm_runtime *runtime = substream->runtime; |
| if (runtime->status->state != SNDRV_PCM_STATE_PREPARED) |
| return -EBADFD; |
| + if (atomic_read(&runtime->buffer_accessing) < 0) |
| + return -EBADFD; /* during hw_params, hw_free or prepare */ |
| if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && |
| !snd_pcm_playback_data(substream)) |
| return -EPIPE; |