[alsa-devel] [PATCH] Free after memory allocation failure in emu10k1

Takashi Iwai tiwai at suse.de
Wed Oct 31 09:13:00 CET 2007


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 at 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) {
> +		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);
>  }
>  
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel at alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 


More information about the Alsa-devel mailing list