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 | |
| 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')
| -rw-r--r-- | sound/core/oss/mixer_oss.c | 10 | ||||
| -rw-r--r-- | sound/core/oss/pcm_oss.c | 2 |
2 files changed, 10 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; |
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 08fde0060fd9..2529e01538e9 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c | |||
| @@ -2457,6 +2457,8 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) | |||
| 2457 | __error2: | 2457 | __error2: |
| 2458 | snd_card_file_remove(pcm->card, file); | 2458 | snd_card_file_remove(pcm->card, file); |
| 2459 | __error1: | 2459 | __error1: |
| 2460 | if (pcm) | ||
| 2461 | snd_card_unref(pcm->card); | ||
| 2460 | return err; | 2462 | return err; |
| 2461 | } | 2463 | } |
| 2462 | 2464 | ||
