]>
Commit | Line | Data |
---|---|---|
0f3bdacc GKH |
1 | From 8bb4d9ce08b0a92ca174e41d92c180328f86173f Mon Sep 17 00:00:00 2001 |
2 | From: Takashi Iwai <tiwai@suse.de> | |
3 | Date: Thu, 8 Nov 2012 14:36:18 +0100 | |
4 | Subject: ALSA: Fix card refcount unbalance | |
5 | ||
6 | From: Takashi Iwai <tiwai@suse.de> | |
7 | ||
8 | commit 8bb4d9ce08b0a92ca174e41d92c180328f86173f upstream. | |
9 | ||
10 | There are uncovered cases whether the card refcount introduced by the | |
11 | commit a0830dbd isn't properly increased or decreased: | |
12 | - OSS PCM and mixer success paths | |
13 | - When lookup function gets NULL | |
14 | ||
15 | This patch fixes these places. | |
16 | ||
17 | Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=50251 | |
18 | ||
19 | Signed-off-by: Takashi Iwai <tiwai@suse.de> | |
20 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
21 | ||
22 | --- | |
23 | sound/core/oss/mixer_oss.c | 1 + | |
24 | sound/core/oss/pcm_oss.c | 1 + | |
25 | sound/core/pcm_native.c | 6 ++++-- | |
26 | sound/core/sound.c | 2 +- | |
27 | sound/core/sound_oss.c | 2 +- | |
28 | 5 files changed, 8 insertions(+), 4 deletions(-) | |
29 | ||
30 | --- a/sound/core/oss/mixer_oss.c | |
31 | +++ b/sound/core/oss/mixer_oss.c | |
32 | @@ -76,6 +76,7 @@ static int snd_mixer_oss_open(struct ino | |
33 | snd_card_unref(card); | |
34 | return -EFAULT; | |
35 | } | |
36 | + snd_card_unref(card); | |
37 | return 0; | |
38 | } | |
39 | ||
40 | --- a/sound/core/oss/pcm_oss.c | |
41 | +++ b/sound/core/oss/pcm_oss.c | |
42 | @@ -2454,6 +2454,7 @@ static int snd_pcm_oss_open(struct inode | |
43 | mutex_unlock(&pcm->open_mutex); | |
44 | if (err < 0) | |
45 | goto __error; | |
46 | + snd_card_unref(pcm->card); | |
47 | return err; | |
48 | ||
49 | __error: | |
50 | --- a/sound/core/pcm_native.c | |
51 | +++ b/sound/core/pcm_native.c | |
52 | @@ -2121,7 +2121,8 @@ static int snd_pcm_playback_open(struct | |
53 | pcm = snd_lookup_minor_data(iminor(inode), | |
54 | SNDRV_DEVICE_TYPE_PCM_PLAYBACK); | |
55 | err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); | |
56 | - snd_card_unref(pcm->card); | |
57 | + if (pcm) | |
58 | + snd_card_unref(pcm->card); | |
59 | return err; | |
60 | } | |
61 | ||
62 | @@ -2134,7 +2135,8 @@ static int snd_pcm_capture_open(struct i | |
63 | pcm = snd_lookup_minor_data(iminor(inode), | |
64 | SNDRV_DEVICE_TYPE_PCM_CAPTURE); | |
65 | err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); | |
66 | - snd_card_unref(pcm->card); | |
67 | + if (pcm) | |
68 | + snd_card_unref(pcm->card); | |
69 | return err; | |
70 | } | |
71 | ||
72 | --- a/sound/core/sound.c | |
73 | +++ b/sound/core/sound.c | |
74 | @@ -115,7 +115,7 @@ void *snd_lookup_minor_data(unsigned int | |
75 | mreg = snd_minors[minor]; | |
76 | if (mreg && mreg->type == type) { | |
77 | private_data = mreg->private_data; | |
78 | - if (mreg->card_ptr) | |
79 | + if (private_data && mreg->card_ptr) | |
80 | atomic_inc(&mreg->card_ptr->refcount); | |
81 | } else | |
82 | private_data = NULL; | |
83 | --- a/sound/core/sound_oss.c | |
84 | +++ b/sound/core/sound_oss.c | |
85 | @@ -54,7 +54,7 @@ void *snd_lookup_oss_minor_data(unsigned | |
86 | mreg = snd_oss_minors[minor]; | |
87 | if (mreg && mreg->type == type) { | |
88 | private_data = mreg->private_data; | |
89 | - if (mreg->card_ptr) | |
90 | + if (private_data && mreg->card_ptr) | |
91 | atomic_inc(&mreg->card_ptr->refcount); | |
92 | } else | |
93 | private_data = NULL; |