Skip to content

Commit 1b73938

Browse files
crwulffgregkh
authored andcommitted
usb: gadget: u_audio: Fix race condition use of controls after free during gadget unbind.
Hang on to the control IDs instead of pointers since those are correctly handled with locks. Fixes: 8fe9a03 ("usb: gadget: u_audio: Rate ctl notifies about current srate (0=stopped)") Fixes: c565ad0 ("usb: gadget: u_audio: Support multiple sampling rates") Fixes: 02de698 ("usb: gadget: u_audio: add bi-directional volume and mute support") Signed-off-by: Chris Wulff <[email protected]> Link: https://lore.kernel.org/stable/CO1PR17MB5419C2BF44D400E4E620C1ADE1172%40CO1PR17MB5419.namprd17.prod.outlook.com Link: https://lore.kernel.org/r/CO1PR17MB5419C2BF44D400E4E620C1ADE1172@CO1PR17MB5419.namprd17.prod.outlook.com Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent c5b324b commit 1b73938

File tree

1 file changed

+9
-10
lines changed

1 file changed

+9
-10
lines changed

drivers/usb/gadget/function/u_audio.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ struct uac_rtd_params {
5757

5858
/* Volume/Mute controls and their state */
5959
int fu_id; /* Feature Unit ID */
60-
struct snd_kcontrol *snd_kctl_volume;
61-
struct snd_kcontrol *snd_kctl_mute;
60+
struct snd_ctl_elem_id snd_kctl_volume_id;
61+
struct snd_ctl_elem_id snd_kctl_mute_id;
6262
s16 volume_min, volume_max, volume_res;
6363
s16 volume;
6464
int mute;
6565

66-
struct snd_kcontrol *snd_kctl_rate; /* read-only current rate */
66+
struct snd_ctl_elem_id snd_kctl_rate_id; /* read-only current rate */
6767
int srate; /* selected samplerate */
6868
int active; /* playback/capture running */
6969

@@ -494,14 +494,13 @@ static inline void free_ep_fback(struct uac_rtd_params *prm, struct usb_ep *ep)
494494
static void set_active(struct uac_rtd_params *prm, bool active)
495495
{
496496
// notifying through the Rate ctrl
497-
struct snd_kcontrol *kctl = prm->snd_kctl_rate;
498497
unsigned long flags;
499498

500499
spin_lock_irqsave(&prm->lock, flags);
501500
if (prm->active != active) {
502501
prm->active = active;
503502
snd_ctl_notify(prm->uac->card, SNDRV_CTL_EVENT_MASK_VALUE,
504-
&kctl->id);
503+
&prm->snd_kctl_rate_id);
505504
}
506505
spin_unlock_irqrestore(&prm->lock, flags);
507506
}
@@ -807,7 +806,7 @@ int u_audio_set_volume(struct g_audio *audio_dev, int playback, s16 val)
807806

808807
if (change)
809808
snd_ctl_notify(uac->card, SNDRV_CTL_EVENT_MASK_VALUE,
810-
&prm->snd_kctl_volume->id);
809+
&prm->snd_kctl_volume_id);
811810

812811
return 0;
813812
}
@@ -856,7 +855,7 @@ int u_audio_set_mute(struct g_audio *audio_dev, int playback, int val)
856855

857856
if (change)
858857
snd_ctl_notify(uac->card, SNDRV_CTL_EVENT_MASK_VALUE,
859-
&prm->snd_kctl_mute->id);
858+
&prm->snd_kctl_mute_id);
860859

861860
return 0;
862861
}
@@ -1331,7 +1330,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
13311330
err = snd_ctl_add(card, kctl);
13321331
if (err < 0)
13331332
goto snd_fail;
1334-
prm->snd_kctl_mute = kctl;
1333+
prm->snd_kctl_mute_id = kctl->id;
13351334
prm->mute = 0;
13361335
}
13371336

@@ -1359,7 +1358,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
13591358
err = snd_ctl_add(card, kctl);
13601359
if (err < 0)
13611360
goto snd_fail;
1362-
prm->snd_kctl_volume = kctl;
1361+
prm->snd_kctl_volume_id = kctl->id;
13631362
prm->volume = fu->volume_max;
13641363
prm->volume_max = fu->volume_max;
13651364
prm->volume_min = fu->volume_min;
@@ -1383,7 +1382,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
13831382
err = snd_ctl_add(card, kctl);
13841383
if (err < 0)
13851384
goto snd_fail;
1386-
prm->snd_kctl_rate = kctl;
1385+
prm->snd_kctl_rate_id = kctl->id;
13871386
}
13881387

13891388
strscpy(card->driver, card_name);

0 commit comments

Comments
 (0)