[alsa-devel] [PATCH] Free after memory allocation failure in emu10k1
I can confirm that it builds. -- Free after memory allocation failure
Signed-off-by: Roel Kluin 12o3l@tiscali.nl --- diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 97c41d7..88f8fb3 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -1894,25 +1894,31 @@ static unsigned char saved_regs_audigy[] = { static int __devinit alloc_pm_buffer(struct snd_emu10k1 *emu) { int size;
size = ARRAY_SIZE(saved_regs); if (emu->audigy) size += ARRAY_SIZE(saved_regs_audigy); emu->saved_ptr = vmalloc(4 * NUM_G * size); if (! emu->saved_ptr) return -ENOMEM; - if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0) + + if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0) { + vfree(emu->saved_ptr); return -ENOMEM; + } + if (emu->card_capabilities->ca0151_chip && - snd_p16v_alloc_pm_buffer(emu) < 0) + snd_p16v_alloc_pm_buffer(emu) < 0) { + vfree(emu->saved_ptr); return -ENOMEM; + } return 0; }
static void free_pm_buffer(struct snd_emu10k1 *emu) { vfree(emu->saved_ptr); snd_emu10k1_efx_free_pm_buffer(emu); if (emu->card_capabilities->ca0151_chip) snd_p16v_free_pm_buffer(emu); } diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 9bf1cd5..a31ad02 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -2634,30 +2634,43 @@ int __devinit snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct
#ifdef CONFIG_PM int __devinit snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu) { int len;
len = emu->audigy ? 0x200 : 0x100; emu->saved_gpr = kmalloc(len * 4, GFP_KERNEL); if (! emu->saved_gpr) return -ENOMEM; + len = emu->audigy ? 0x100 : 0xa0; emu->tram_val_saved = kmalloc(len * 4, GFP_KERNEL); + if (! emu->tram_val_saved) + goto free_gpr; + emu->tram_addr_saved = kmalloc(len * 4, GFP_KERNEL); - if (! emu->tram_val_saved || ! emu->tram_addr_saved) - return -ENOMEM; + if (! emu->tram_addr_saved) + goto free_tram_val; + len = emu->audigy ? 2 * 1024 : 2 * 512; emu->saved_icode = vmalloc(len * 4); if (! emu->saved_icode) - return -ENOMEM; + goto free_tram_addr; + return 0; +free_gpr: + kfree(emu->saved_gpr); +free_tram_val: + kfree(emu->tram_val_saved); +free_tram_addr: + kfree(emu->tram_addr_saved); + return -ENOMEM; }
void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu) { kfree(emu->saved_gpr); kfree(emu->tram_val_saved); kfree(emu->tram_addr_saved); vfree(emu->saved_icode); }
At Wed, 31 Oct 2007 02:19:36 +0100, Roel Kluin wrote:
I can confirm that it builds.
Free after memory allocation failure
Signed-off-by: Roel Kluin 12o3l@tiscali.nl
Thanks for the patch.
But, this fix isn't correct because snd_emu10k1_free() is always called in the error path. snd_emu10k1_free() calls free_pm_buffer() that eventually releases all buffers allocated via alloc_pm_buffer() (and *_alloc_pm_buffer() from it).
Takashi
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 97c41d7..88f8fb3 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -1894,25 +1894,31 @@ static unsigned char saved_regs_audigy[] = { static int __devinit alloc_pm_buffer(struct snd_emu10k1 *emu) { int size;
size = ARRAY_SIZE(saved_regs); if (emu->audigy) size += ARRAY_SIZE(saved_regs_audigy); emu->saved_ptr = vmalloc(4 * NUM_G * size); if (! emu->saved_ptr) return -ENOMEM;
- if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0)
- if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0) {
return -ENOMEM;vfree(emu->saved_ptr);
- }
- if (emu->card_capabilities->ca0151_chip &&
snd_p16v_alloc_pm_buffer(emu) < 0)
snd_p16v_alloc_pm_buffer(emu) < 0) {
return -ENOMEM;vfree(emu->saved_ptr);
- } return 0;
}
static void free_pm_buffer(struct snd_emu10k1 *emu) { vfree(emu->saved_ptr); snd_emu10k1_efx_free_pm_buffer(emu); if (emu->card_capabilities->ca0151_chip) snd_p16v_free_pm_buffer(emu); } diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 9bf1cd5..a31ad02 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -2634,30 +2634,43 @@ int __devinit snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct
#ifdef CONFIG_PM int __devinit snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu) { int len;
len = emu->audigy ? 0x200 : 0x100; emu->saved_gpr = kmalloc(len * 4, GFP_KERNEL); if (! emu->saved_gpr) return -ENOMEM;
- len = emu->audigy ? 0x100 : 0xa0; emu->tram_val_saved = kmalloc(len * 4, GFP_KERNEL);
- if (! emu->tram_val_saved)
goto free_gpr;
- emu->tram_addr_saved = kmalloc(len * 4, GFP_KERNEL);
- if (! emu->tram_val_saved || ! emu->tram_addr_saved)
return -ENOMEM;
- if (! emu->tram_addr_saved)
goto free_tram_val;
- len = emu->audigy ? 2 * 1024 : 2 * 512; emu->saved_icode = vmalloc(len * 4); if (! emu->saved_icode)
return -ENOMEM;
goto free_tram_addr;
- return 0;
+free_gpr:
- kfree(emu->saved_gpr);
+free_tram_val:
- kfree(emu->tram_val_saved);
+free_tram_addr:
- kfree(emu->tram_addr_saved);
return -ENOMEM;
}
void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu) { kfree(emu->saved_gpr); kfree(emu->tram_val_saved); kfree(emu->tram_addr_saved); vfree(emu->saved_icode); }
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
participants (2)
-
Roel Kluin
-
Takashi Iwai