[PATCH 3/5] ALSA: rawmidi: Take open_mutex around parameter changes
Takashi Iwai
tiwai at suse.de
Fri Jun 17 16:40:49 CEST 2022
The input/output parameter changes are pretty intrusive, possibly
involving with the buffer resizing operation. Hence those should be
performed exclusively; otherwise some ugly race could happen.
This patch puts the existing open_mutex for snd_rawmidi_input_params()
and *_output_params() for protecting the concurrent calls. Since
those are exported, it's also meant for hardening from the external
calls, too.
Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
sound/core/rawmidi.c | 39 +++++++++++++++++++++++++--------------
1 file changed, 25 insertions(+), 14 deletions(-)
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 0a00f37d8c42..7fd6b369d46f 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -712,11 +712,19 @@ static int resize_runtime_buffer(struct snd_rawmidi_substream *substream,
int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
struct snd_rawmidi_params *params)
{
- if (substream->append && substream->use_count > 1)
- return -EBUSY;
+ int err;
+
snd_rawmidi_drain_output(substream);
- substream->active_sensing = !params->no_active_sensing;
- return resize_runtime_buffer(substream, params, false);
+ mutex_lock(&substream->rmidi->open_mutex);
+ if (substream->append && substream->use_count > 1)
+ err = -EBUSY;
+ else
+ err = resize_runtime_buffer(substream, params, false);
+
+ if (!err)
+ substream->active_sensing = !params->no_active_sensing;
+ mutex_unlock(&substream->rmidi->open_mutex);
+ return err;
}
EXPORT_SYMBOL(snd_rawmidi_output_params);
@@ -727,19 +735,22 @@ int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
unsigned int clock_type = params->mode & SNDRV_RAWMIDI_MODE_CLOCK_MASK;
int err;
+ snd_rawmidi_drain_input(substream);
+ mutex_lock(&substream->rmidi->open_mutex);
if (framing == SNDRV_RAWMIDI_MODE_FRAMING_NONE && clock_type != SNDRV_RAWMIDI_MODE_CLOCK_NONE)
- return -EINVAL;
+ err = -EINVAL;
else if (clock_type > SNDRV_RAWMIDI_MODE_CLOCK_MONOTONIC_RAW)
- return -EINVAL;
- if (framing > SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP)
- return -EINVAL;
- snd_rawmidi_drain_input(substream);
- err = resize_runtime_buffer(substream, params, true);
- if (err < 0)
- return err;
+ err = -EINVAL;
+ else if (framing > SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP)
+ err = -EINVAL;
+ else
+ err = resize_runtime_buffer(substream, params, true);
- substream->framing = framing;
- substream->clock_type = clock_type;
+ if (!err) {
+ substream->framing = framing;
+ substream->clock_type = clock_type;
+ }
+ mutex_unlock(&substream->rmidi->open_mutex);
return 0;
}
EXPORT_SYMBOL(snd_rawmidi_input_params);
--
2.35.3
More information about the Alsa-devel
mailing list