Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: gus: Fix memory leaks at memory allocator error paths

When snd_gf1_mem_xalloc() returns NULL, the current code still leaves
the formerly allocated block.name string but returns an error
immediately. This patch does code-refactoring to move the kstrdup()
call itself into snd_gf1_mem_xalloc() and deals with the resource free
in the helper code by itself for fixing those memory leaks.

Suggested-by: Jaroslav Kysela <perex@perex.cz>
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20211213132444.22385-2-tiwai@suse.de
Link: https://lore.kernel.org/r/20211213141512.27359-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>

+12 -12
+12 -12
sound/isa/gus/gus_mem.c
··· 24 24 } 25 25 } 26 26 27 - static struct snd_gf1_mem_block *snd_gf1_mem_xalloc(struct snd_gf1_mem * alloc, 28 - struct snd_gf1_mem_block * block) 27 + static struct snd_gf1_mem_block * 28 + snd_gf1_mem_xalloc(struct snd_gf1_mem *alloc, struct snd_gf1_mem_block *block, 29 + const char *name) 29 30 { 30 31 struct snd_gf1_mem_block *pblock, *nblock; 31 32 ··· 34 33 if (nblock == NULL) 35 34 return NULL; 36 35 *nblock = *block; 36 + nblock->name = kstrdup(name, GFP_KERNEL); 37 + if (!nblock->name) { 38 + kfree(nblock); 39 + return NULL; 40 + } 41 + 37 42 pblock = alloc->first; 38 43 while (pblock) { 39 44 if (pblock->ptr > nblock->ptr) { ··· 205 198 if (share_id != NULL) 206 199 memcpy(&block.share_id, share_id, sizeof(block.share_id)); 207 200 block.owner = owner; 208 - block.name = kstrdup(name, GFP_KERNEL); 209 - if (block.name == NULL) { 210 - snd_gf1_mem_lock(alloc, 1); 211 - return NULL; 212 - } 213 - nblock = snd_gf1_mem_xalloc(alloc, &block); 201 + nblock = snd_gf1_mem_xalloc(alloc, &block, name); 214 202 snd_gf1_mem_lock(alloc, 1); 215 203 return nblock; 216 204 } ··· 242 240 if (gus->gf1.enh_mode) { 243 241 block.ptr = 0; 244 242 block.size = 1024; 245 - block.name = kstrdup("InterWave LFOs", GFP_KERNEL); 246 - if (block.name == NULL || snd_gf1_mem_xalloc(alloc, &block) == NULL) 243 + if (!snd_gf1_mem_xalloc(alloc, &block, "InterWave LFOs")) 247 244 return -ENOMEM; 248 245 } 249 246 block.ptr = gus->gf1.default_voice_address; 250 247 block.size = 4; 251 - block.name = kstrdup("Voice default (NULL's)", GFP_KERNEL); 252 - if (block.name == NULL || snd_gf1_mem_xalloc(alloc, &block) == NULL) 248 + if (!snd_gf1_mem_xalloc(alloc, &block, "Voice default (NULL's)")) 253 249 return -ENOMEM; 254 250 #ifdef CONFIG_SND_DEBUG 255 251 snd_card_ro_proc_new(gus->card, "gusmem", gus, snd_gf1_mem_info_read);