From 40edba667959559aa4385a5ec047420fcfeb5f03 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 7 Nov 2012 12:44:12 +0100 Subject: ALSA: Add a reference counter to card instance commit a0830dbd4e42b38aefdf3fb61ba5019a1a99ea85 upstream. For more strict protection for wild disconnections, a refcount is introduced to the card instance, and let it up/down when an object is referred via snd_lookup_*() in the open ops. The free-after-last-close check is also changed to check this refcount instead of the empty list, too. Reported-by: Matthieu CASTET Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/core/hwdep.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'sound/core/hwdep.c') diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index a70ee7f..dbc3556 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c @@ -99,8 +99,10 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) if (hw == NULL) return -ENODEV; - if (!try_module_get(hw->card->module)) + if (!try_module_get(hw->card->module)) { + snd_card_unref(hw->card); return -EFAULT; + } init_waitqueue_entry(&wait, current); add_wait_queue(&hw->open_wait, &wait); @@ -147,6 +149,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) mutex_unlock(&hw->open_mutex); if (err < 0) module_put(hw->card->module); + snd_card_unref(hw->card); return err; } -- cgit v1.1 From 8a7173c58c8a1e25d7b2d572f045da837bb373bf Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 7 Nov 2012 12:44:13 +0100 Subject: ALSA: Avoid endless sleep after disconnect commit 0914f7961babbf28aaa2f19b453951fb4841c03f upstream. When disconnect callback is called, each component should wake up sleepers and check card->shutdown flag for avoiding the endless sleep blocking the proper resource release. Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/core/hwdep.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sound/core/hwdep.c') diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index dbc3556..32fb2fe 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c @@ -130,6 +130,10 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) mutex_unlock(&hw->open_mutex); schedule(); mutex_lock(&hw->open_mutex); + if (hw->card->shutdown) { + err = -ENODEV; + break; + } if (signal_pending(current)) { err = -ERESTARTSYS; break; @@ -454,12 +458,15 @@ static int snd_hwdep_dev_disconnect(struct snd_device *device) mutex_unlock(®ister_mutex); return -EINVAL; } + mutex_lock(&hwdep->open_mutex); + wake_up(&hwdep->open_wait); #ifdef CONFIG_SND_OSSEMUL if (hwdep->ossreg) snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device); #endif snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device); list_del_init(&hwdep->list); + mutex_unlock(&hwdep->open_mutex); mutex_unlock(®ister_mutex); return 0; } -- cgit v1.1