Merge "USB: gadget: f_audio_source: Fix use after free in audio_unbind"
diff --git a/drivers/usb/gadget/f_audio_source.c b/drivers/usb/gadget/f_audio_source.c
index 0471f888..34faf6d 100644
--- a/drivers/usb/gadget/f_audio_source.c
+++ b/drivers/usb/gadget/f_audio_source.c
@@ -628,7 +628,10 @@
audio_request_free(req, audio->in_ep);
snd_card_free_when_closed(audio->card);
- kfree(audio);
+ audio->card = NULL;
+ audio->pcm = NULL;
+ audio->substream = NULL;
+ audio->in_ep = NULL;
}
static void audio_pcm_playback_start(struct audio_dev *audio)
@@ -744,6 +747,21 @@
return ret;
}
+static struct audio_dev _audio_dev = {
+ .func = {
+ .name = "audio_source",
+ .bind = audio_bind,
+ .unbind = audio_unbind,
+ .set_alt = audio_set_alt,
+ .setup = audio_setup,
+ .disable = audio_disable,
+ .descriptors = fs_audio_desc,
+ .hs_descriptors = hs_audio_desc,
+ },
+ .lock = __SPIN_LOCK_UNLOCKED(_audio_dev.lock),
+ .idle_reqs = LIST_HEAD_INIT(_audio_dev.idle_reqs),
+};
+
static struct snd_pcm_ops audio_playback_ops = {
.open = audio_pcm_open,
.close = audio_pcm_close,
@@ -766,28 +784,12 @@
config->card = -1;
config->device = -1;
- audio = kzalloc(sizeof *audio, GFP_KERNEL);
- if (!audio)
- return -ENOMEM;
-
- audio->func.name = "audio_source";
-
- spin_lock_init(&audio->lock);
-
- audio->func.descriptors = fs_audio_desc;
- audio->func.hs_descriptors = hs_audio_desc;
- audio->func.bind = audio_bind;
- audio->func.unbind = audio_unbind;
- audio->func.set_alt = audio_set_alt;
- audio->func.setup = audio_setup;
- audio->func.disable = audio_disable;
-
- INIT_LIST_HEAD(&audio->idle_reqs);
+ audio = &_audio_dev;
err = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
THIS_MODULE, 0, &card);
if (err)
- goto snd_card_fail;
+ return err;
snd_card_set_dev(card, &c->cdev->gadget->dev);
@@ -826,7 +828,5 @@
register_fail:
pcm_fail:
snd_card_free(audio->card);
-snd_card_fail:
- kfree(audio);
return err;
}