Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c679a08 authored by Manu Gautam's avatar Manu Gautam
Browse files

USB: gadget: midi: Fix use-after-free after midi_unbind



If midi composition is unbound while streaming is going
on then there is a possibility of in/out_trigger pcm
routines accessing midi structure after it is already
freed on function unbind.

CRs-fixed: 2020461
Change-Id: Ifb3141f3a26f073f6df7c4ae7e821c828d723a4f
Signed-off-by: default avatarManu Gautam <mgautam@codeaurora.org>
parent d603d283
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -92,6 +92,8 @@ struct f_midi {
	unsigned int buflen, qlen;
};

static struct f_midi *the_midi;

static inline struct f_midi *func_to_midi(struct usb_function *f)
{
	return container_of(f, struct f_midi, func);
@@ -413,6 +415,7 @@ static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f)

	usb_free_all_descriptors(f);
	kfree(midi);
	the_midi = NULL;
}

static int f_midi_snd_free(struct snd_device *device)
@@ -586,6 +589,10 @@ static int f_midi_in_open(struct snd_rawmidi_substream *substream)
{
	struct f_midi *midi = substream->rmidi->private_data;

	/* check if midi got disabled or re-enabled quickly */
	if (midi != the_midi)
		return -ENODEV;

	if (!midi->in_port[substream->number])
		return -EINVAL;

@@ -607,6 +614,10 @@ static void f_midi_in_trigger(struct snd_rawmidi_substream *substream, int up)
{
	struct f_midi *midi = substream->rmidi->private_data;

	/* check if midi got disabled or re-enabled quickly */
	if (midi != the_midi)
		return;

	if (!midi->in_port[substream->number])
		return;

@@ -620,6 +631,10 @@ static int f_midi_out_open(struct snd_rawmidi_substream *substream)
{
	struct f_midi *midi = substream->rmidi->private_data;

	/* check if midi got disabled or re-enabled quickly */
	if (midi != the_midi)
		return -ENODEV;

	if (substream->number >= MAX_PORTS)
		return -EINVAL;

@@ -640,6 +655,10 @@ static void f_midi_out_trigger(struct snd_rawmidi_substream *substream, int up)
{
	struct f_midi *midi = substream->rmidi->private_data;

	/* check if midi got disabled or re-enabled quickly */
	if (midi != the_midi)
		return;

	VDBG(midi, "%s()\n", __func__);

	if (up)
@@ -985,6 +1004,7 @@ int /* __init */ f_midi_bind_config(struct usb_configuration *c,
	if (status)
		goto setup_fail;

	the_midi = midi;

	if (config) {
		config->card = midi->rmidi->card->number;