sound: Fix esoteric double free in the dummy sound driver.
The dummy driver uses runtime->private_free but still frees its pcm structures on error paths. This is esoteric because the error paths in question are unreachable. Thus the bug is only a problem when someone copies this code into other drivers. Signed-off-by: Daniel R Thompson <daniel.thompson@st.com> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
committed by
Jaroslav Kysela
parent
8daaaa97d6
commit
54e8e21ed2
@@ -354,6 +354,7 @@ static int snd_card_dummy_playback_open(struct snd_pcm_substream *substream)
|
|||||||
if ((dpcm = new_pcm_stream(substream)) == NULL)
|
if ((dpcm = new_pcm_stream(substream)) == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
runtime->private_data = dpcm;
|
runtime->private_data = dpcm;
|
||||||
|
/* makes the infrastructure responsible for freeing dpcm */
|
||||||
runtime->private_free = snd_card_dummy_runtime_free;
|
runtime->private_free = snd_card_dummy_runtime_free;
|
||||||
runtime->hw = snd_card_dummy_playback;
|
runtime->hw = snd_card_dummy_playback;
|
||||||
if (substream->pcm->device & 1) {
|
if (substream->pcm->device & 1) {
|
||||||
@@ -362,10 +363,8 @@ static int snd_card_dummy_playback_open(struct snd_pcm_substream *substream)
|
|||||||
}
|
}
|
||||||
if (substream->pcm->device & 2)
|
if (substream->pcm->device & 2)
|
||||||
runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID);
|
runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID);
|
||||||
if ((err = add_playback_constraints(runtime)) < 0) {
|
if ((err = add_playback_constraints(runtime)) < 0)
|
||||||
kfree(dpcm);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -379,6 +378,7 @@ static int snd_card_dummy_capture_open(struct snd_pcm_substream *substream)
|
|||||||
if ((dpcm = new_pcm_stream(substream)) == NULL)
|
if ((dpcm = new_pcm_stream(substream)) == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
runtime->private_data = dpcm;
|
runtime->private_data = dpcm;
|
||||||
|
/* makes the infrastructure responsible for freeing dpcm */
|
||||||
runtime->private_free = snd_card_dummy_runtime_free;
|
runtime->private_free = snd_card_dummy_runtime_free;
|
||||||
runtime->hw = snd_card_dummy_capture;
|
runtime->hw = snd_card_dummy_capture;
|
||||||
if (substream->pcm->device == 1) {
|
if (substream->pcm->device == 1) {
|
||||||
@@ -387,10 +387,8 @@ static int snd_card_dummy_capture_open(struct snd_pcm_substream *substream)
|
|||||||
}
|
}
|
||||||
if (substream->pcm->device & 2)
|
if (substream->pcm->device & 2)
|
||||||
runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID);
|
runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID);
|
||||||
if ((err = add_capture_constraints(runtime)) < 0) {
|
if ((err = add_capture_constraints(runtime)) < 0)
|
||||||
kfree(dpcm);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user