mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-06 08:46:46 +00:00
ALSA: oss: Fix potential deadlock at unregistration
commit 97d917879d
upstream.
We took sound_oss_mutex around the calls of unregister_sound_special()
at unregistering OSS devices. This may, however, lead to a deadlock,
because we manage the card release via the card's device object, and
the release may happen at unregister_sound_special() call -- which
will take sound_oss_mutex again in turn.
Although the deadlock might be fixed by relaxing the rawmidi mutex in
the previous commit, it's safer to move unregister_sound_special()
calls themselves out of the sound_oss_mutex, too. The call is
race-safe as the function has a spinlock protection by itself.
Link: https://lore.kernel.org/r/CAB7eexJP7w1B0mVgDF0dQ+gWor7UdkiwPczmL7pn91xx8xpzOA@mail.gmail.com
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20221011070147.7611-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
c3024d1bd8
commit
4049dbabf2
1 changed files with 9 additions and 4 deletions
|
@ -177,7 +177,6 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
|
|||
mutex_unlock(&sound_oss_mutex);
|
||||
return -ENOENT;
|
||||
}
|
||||
unregister_sound_special(minor);
|
||||
switch (SNDRV_MINOR_OSS_DEVICE(minor)) {
|
||||
case SNDRV_MINOR_OSS_PCM:
|
||||
track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_AUDIO);
|
||||
|
@ -189,12 +188,18 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
|
|||
track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI1);
|
||||
break;
|
||||
}
|
||||
if (track2 >= 0) {
|
||||
unregister_sound_special(track2);
|
||||
if (track2 >= 0)
|
||||
snd_oss_minors[track2] = NULL;
|
||||
}
|
||||
snd_oss_minors[minor] = NULL;
|
||||
mutex_unlock(&sound_oss_mutex);
|
||||
|
||||
/* call unregister_sound_special() outside sound_oss_mutex;
|
||||
* otherwise may deadlock, as it can trigger the release of a card
|
||||
*/
|
||||
unregister_sound_special(minor);
|
||||
if (track2 >= 0)
|
||||
unregister_sound_special(track2);
|
||||
|
||||
kfree(mptr);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue