aboutsummaryrefslogtreecommitdiffstats
path: root/sound/drivers/dummy.c
diff options
context:
space:
mode:
authorDaniel THOMPSON <daniel.thompson@st.com>2008-08-15 05:53:38 -0400
committerJaroslav Kysela <perex@perex.cz>2008-08-15 06:38:14 -0400
commit54e8e21ed21ca8788aa75294067494abebf9d550 (patch)
tree354640ce67641af2632212edf6a29fb8e7a6fd9c /sound/drivers/dummy.c
parent8daaaa97d6420c7e8b02c12ce591bb29fd959c62 (diff)
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>
Diffstat (limited to 'sound/drivers/dummy.c')
-rw-r--r--sound/drivers/dummy.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index c873243e6713..4f900d8b92ce 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -354,6 +354,7 @@ static int snd_card_dummy_playback_open(struct snd_pcm_substream *substream)
354 if ((dpcm = new_pcm_stream(substream)) == NULL) 354 if ((dpcm = new_pcm_stream(substream)) == NULL)
355 return -ENOMEM; 355 return -ENOMEM;
356 runtime->private_data = dpcm; 356 runtime->private_data = dpcm;
357 /* makes the infrastructure responsible for freeing dpcm */
357 runtime->private_free = snd_card_dummy_runtime_free; 358 runtime->private_free = snd_card_dummy_runtime_free;
358 runtime->hw = snd_card_dummy_playback; 359 runtime->hw = snd_card_dummy_playback;
359 if (substream->pcm->device & 1) { 360 if (substream->pcm->device & 1) {
@@ -362,10 +363,8 @@ static int snd_card_dummy_playback_open(struct snd_pcm_substream *substream)
362 } 363 }
363 if (substream->pcm->device & 2) 364 if (substream->pcm->device & 2)
364 runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID); 365 runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID);
365 if ((err = add_playback_constraints(runtime)) < 0) { 366 if ((err = add_playback_constraints(runtime)) < 0)
366 kfree(dpcm);
367 return err; 367 return err;
368 }
369 368
370 return 0; 369 return 0;
371} 370}
@@ -379,6 +378,7 @@ static int snd_card_dummy_capture_open(struct snd_pcm_substream *substream)
379 if ((dpcm = new_pcm_stream(substream)) == NULL) 378 if ((dpcm = new_pcm_stream(substream)) == NULL)
380 return -ENOMEM; 379 return -ENOMEM;
381 runtime->private_data = dpcm; 380 runtime->private_data = dpcm;
381 /* makes the infrastructure responsible for freeing dpcm */
382 runtime->private_free = snd_card_dummy_runtime_free; 382 runtime->private_free = snd_card_dummy_runtime_free;
383 runtime->hw = snd_card_dummy_capture; 383 runtime->hw = snd_card_dummy_capture;
384 if (substream->pcm->device == 1) { 384 if (substream->pcm->device == 1) {
@@ -387,10 +387,8 @@ static int snd_card_dummy_capture_open(struct snd_pcm_substream *substream)
387 } 387 }
388 if (substream->pcm->device & 2) 388 if (substream->pcm->device & 2)
389 runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID); 389 runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID);
390 if ((err = add_capture_constraints(runtime)) < 0) { 390 if ((err = add_capture_constraints(runtime)) < 0)
391 kfree(dpcm);
392 return err; 391 return err;
393 }
394 392
395 return 0; 393 return 0;
396} 394}