Commit 94b98194 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: rawmidi: Take open_mutex around parameter changes

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.

Link: https://lore.kernel.org/r/20220617144051.18985-4-tiwai@suse.de


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent f1d40433
Loading
Loading
Loading
Loading
+25 −14
Original line number Diff line number Diff line
@@ -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);
	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;
	return resize_runtime_buffer(substream, params, false);
	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 = -EINVAL;
	else if (framing > SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP)
		err = -EINVAL;
	else
		err = resize_runtime_buffer(substream, params, true);
	if (err < 0)
		return err;

	if (!err) {
		substream->framing = framing;
		substream->clock_type = clock_type;
	}
	mutex_unlock(&substream->rmidi->open_mutex);
	return 0;
}
EXPORT_SYMBOL(snd_rawmidi_input_params);