Skip to contentSkip to conversation

Free after memory allocation failure in emu10k1

PATCH In review Roel Kluin 2 participants 2 messages Oct 31, 2007 Sound

lore
Share & tools
lore

Roel Kluin

author
#0 lore raw

PATCH 1/1 Free after memory allocation failure in emu10k1

I can confirm that it builds.
--
Free after memory allocation failure

---

sound/pci/emu10k1/emu10k1_main.c +8 -2
index 97c41d7..88f8fb3 100644
@@ -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);
 }
sound/pci/emu10k1/emufx.c +16 -3
index 9bf1cd5..a31ad02 100644
@@ -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);
 }
#1 lore raw

At Wed, 31 Oct 2007 02:19:36 +0100,

Quoted 6 lines · Roel Kluin

I can confirm that it builds.
--
Free after memory allocation failure

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

Quoted 95 lines

---

sound/pci/emu10k1/emu10k1_main.c +8 -2
index 97c41d7..88f8fb3 100644
@@ -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);
 }
sound/pci/emu10k1/emufx.c +16 -3
index 9bf1cd5..a31ad02 100644
@@ -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
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel