Skip to content

Commit

Permalink
ALSA: Fix card refcount unbalance
Browse files Browse the repository at this point in the history
commit 8bb4d9c upstream.

There are uncovered cases whether the card refcount introduced by the
commit a0830db isn't properly increased or decreased:
- OSS PCM and mixer success paths
- When lookup function gets NULL

This patch fixes these places.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=50251

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Takashi Iwai authored and Greg Kroah-Hartman committed Nov 17, 2012
1 parent 7565b21 commit f49c1be
Show file tree
Hide file tree
Showing 5 changed files with 8 additions and 4 deletions.
1 change: 1 addition & 0 deletions sound/core/oss/mixer_oss.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file)
snd_card_unref(card);
return -EFAULT;
}
snd_card_unref(card);
return 0;
}

Expand Down
1 change: 1 addition & 0 deletions sound/core/oss/pcm_oss.c
Original file line number Diff line number Diff line change
Expand Up @@ -2454,6 +2454,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
mutex_unlock(&pcm->open_mutex);
if (err < 0)
goto __error;
snd_card_unref(pcm->card);
return err;

__error:
Expand Down
6 changes: 4 additions & 2 deletions sound/core/pcm_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -2121,7 +2121,8 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file)
pcm = snd_lookup_minor_data(iminor(inode),
SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK);
snd_card_unref(pcm->card);
if (pcm)
snd_card_unref(pcm->card);
return err;
}

Expand All @@ -2134,7 +2135,8 @@ static int snd_pcm_capture_open(struct inode *inode, struct file *file)
pcm = snd_lookup_minor_data(iminor(inode),
SNDRV_DEVICE_TYPE_PCM_CAPTURE);
err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE);
snd_card_unref(pcm->card);
if (pcm)
snd_card_unref(pcm->card);
return err;
}

Expand Down
2 changes: 1 addition & 1 deletion sound/core/sound.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
mreg = snd_minors[minor];
if (mreg && mreg->type == type) {
private_data = mreg->private_data;
if (mreg->card_ptr)
if (private_data && mreg->card_ptr)
atomic_inc(&mreg->card_ptr->refcount);
} else
private_data = NULL;
Expand Down
2 changes: 1 addition & 1 deletion sound/core/sound_oss.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void *snd_lookup_oss_minor_data(unsigned int minor, int type)
mreg = snd_oss_minors[minor];
if (mreg && mreg->type == type) {
private_data = mreg->private_data;
if (mreg->card_ptr)
if (private_data && mreg->card_ptr)
atomic_inc(&mreg->card_ptr->refcount);
} else
private_data = NULL;
Expand Down

0 comments on commit f49c1be

Please sign in to comment.