diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-10-16 07:05:59 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-10-30 06:07:10 -0400 |
commit | a0830dbd4e42b38aefdf3fb61ba5019a1a99ea85 (patch) | |
tree | 4dc74b708a07b56d12ed72a34d0a2e0cb8c8b9d4 /sound/core/oss/mixer_oss.c | |
parent | 888ea7d5ac6815ba16b3b3a20f665a92c7af6724 (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/oss/mixer_oss.c')
-rw-r--r-- | sound/core/oss/mixer_oss.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 29f6ded02555..a9a2e63c0222 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c | |||
@@ -52,14 +52,19 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file) | |||
52 | SNDRV_OSS_DEVICE_TYPE_MIXER); | 52 | SNDRV_OSS_DEVICE_TYPE_MIXER); |
53 | if (card == NULL) | 53 | if (card == NULL) |
54 | return -ENODEV; | 54 | return -ENODEV; |
55 | if (card->mixer_oss == NULL) | 55 | if (card->mixer_oss == NULL) { |
56 | snd_card_unref(card); | ||
56 | return -ENODEV; | 57 | return -ENODEV; |
58 | } | ||
57 | err = snd_card_file_add(card, file); | 59 | err = snd_card_file_add(card, file); |
58 | if (err < 0) | 60 | if (err < 0) { |
61 | snd_card_unref(card); | ||
59 | return err; | 62 | return err; |
63 | } | ||
60 | fmixer = kzalloc(sizeof(*fmixer), GFP_KERNEL); | 64 | fmixer = kzalloc(sizeof(*fmixer), GFP_KERNEL); |
61 | if (fmixer == NULL) { | 65 | if (fmixer == NULL) { |
62 | snd_card_file_remove(card, file); | 66 | snd_card_file_remove(card, file); |
67 | snd_card_unref(card); | ||
63 | return -ENOMEM; | 68 | return -ENOMEM; |
64 | } | 69 | } |
65 | fmixer->card = card; | 70 | fmixer->card = card; |
@@ -68,6 +73,7 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file) | |||
68 | if (!try_module_get(card->module)) { | 73 | if (!try_module_get(card->module)) { |
69 | kfree(fmixer); | 74 | kfree(fmixer); |
70 | snd_card_file_remove(card, file); | 75 | snd_card_file_remove(card, file); |
76 | snd_card_unref(card); | ||
71 | return -EFAULT; | 77 | return -EFAULT; |
72 | } | 78 | } |
73 | return 0; | 79 | return 0; |