aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/control.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-10-16 07:05:59 -0400
committerTakashi Iwai <tiwai@suse.de>2012-10-30 06:07:10 -0400
commita0830dbd4e42b38aefdf3fb61ba5019a1a99ea85 (patch)
tree4dc74b708a07b56d12ed72a34d0a2e0cb8c8b9d4 /sound/core/control.c
parent888ea7d5ac6815ba16b3b3a20f665a92c7af6724 (diff)
ALSA: Add a reference counter to card instance
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 <matthieu.castet@parrot.com> Cc: <stable@vger.kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/core/control.c')
-rw-r--r--sound/core/control.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/sound/core/control.c b/sound/core/control.c
index 7e86a5b9f3b5..9768a3963c8f 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -86,6 +86,7 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
86 write_lock_irqsave(&card->ctl_files_rwlock, flags); 86 write_lock_irqsave(&card->ctl_files_rwlock, flags);
87 list_add_tail(&ctl->list, &card->ctl_files); 87 list_add_tail(&ctl->list, &card->ctl_files);
88 write_unlock_irqrestore(&card->ctl_files_rwlock, flags); 88 write_unlock_irqrestore(&card->ctl_files_rwlock, flags);
89 snd_card_unref(card);
89 return 0; 90 return 0;
90 91
91 __error: 92 __error:
@@ -93,6 +94,8 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
93 __error2: 94 __error2:
94 snd_card_file_remove(card, file); 95 snd_card_file_remove(card, file);
95 __error1: 96 __error1:
97 if (card)
98 snd_card_unref(card);
96 return err; 99 return err;
97} 100}
98 101