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>
This commit is contained in:
parent
c2f5141540
commit
dec242b6a8
|
@ -24,8 +24,9 @@ void snd_gf1_mem_lock(struct snd_gf1_mem * alloc, int xup)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct snd_gf1_mem_block *snd_gf1_mem_xalloc(struct snd_gf1_mem * alloc,
|
static struct snd_gf1_mem_block *
|
||||||
struct snd_gf1_mem_block * block)
|
snd_gf1_mem_xalloc(struct snd_gf1_mem *alloc, struct snd_gf1_mem_block *block,
|
||||||
|
const char *name)
|
||||||
{
|
{
|
||||||
struct snd_gf1_mem_block *pblock, *nblock;
|
struct snd_gf1_mem_block *pblock, *nblock;
|
||||||
|
|
||||||
|
@ -33,6 +34,12 @@ static struct snd_gf1_mem_block *snd_gf1_mem_xalloc(struct snd_gf1_mem * alloc,
|
||||||
if (nblock == NULL)
|
if (nblock == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
*nblock = *block;
|
*nblock = *block;
|
||||||
|
nblock->name = kstrdup(name, GFP_KERNEL);
|
||||||
|
if (!nblock->name) {
|
||||||
|
kfree(nblock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
pblock = alloc->first;
|
pblock = alloc->first;
|
||||||
while (pblock) {
|
while (pblock) {
|
||||||
if (pblock->ptr > nblock->ptr) {
|
if (pblock->ptr > nblock->ptr) {
|
||||||
|
@ -198,12 +205,7 @@ struct snd_gf1_mem_block *snd_gf1_mem_alloc(struct snd_gf1_mem * alloc, int owne
|
||||||
if (share_id != NULL)
|
if (share_id != NULL)
|
||||||
memcpy(&block.share_id, share_id, sizeof(block.share_id));
|
memcpy(&block.share_id, share_id, sizeof(block.share_id));
|
||||||
block.owner = owner;
|
block.owner = owner;
|
||||||
block.name = kstrdup(name, GFP_KERNEL);
|
nblock = snd_gf1_mem_xalloc(alloc, &block, name);
|
||||||
if (block.name == NULL) {
|
|
||||||
snd_gf1_mem_lock(alloc, 1);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
nblock = snd_gf1_mem_xalloc(alloc, &block);
|
|
||||||
snd_gf1_mem_lock(alloc, 1);
|
snd_gf1_mem_lock(alloc, 1);
|
||||||
return nblock;
|
return nblock;
|
||||||
}
|
}
|
||||||
|
@ -240,14 +242,12 @@ int snd_gf1_mem_init(struct snd_gus_card * gus)
|
||||||
if (gus->gf1.enh_mode) {
|
if (gus->gf1.enh_mode) {
|
||||||
block.ptr = 0;
|
block.ptr = 0;
|
||||||
block.size = 1024;
|
block.size = 1024;
|
||||||
block.name = kstrdup("InterWave LFOs", GFP_KERNEL);
|
if (!snd_gf1_mem_xalloc(alloc, &block, "InterWave LFOs"))
|
||||||
if (block.name == NULL || snd_gf1_mem_xalloc(alloc, &block) == NULL)
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
block.ptr = gus->gf1.default_voice_address;
|
block.ptr = gus->gf1.default_voice_address;
|
||||||
block.size = 4;
|
block.size = 4;
|
||||||
block.name = kstrdup("Voice default (NULL's)", GFP_KERNEL);
|
if (!snd_gf1_mem_xalloc(alloc, &block, "Voice default (NULL's)"))
|
||||||
if (block.name == NULL || snd_gf1_mem_xalloc(alloc, &block) == NULL)
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
#ifdef CONFIG_SND_DEBUG
|
#ifdef CONFIG_SND_DEBUG
|
||||||
snd_card_ro_proc_new(gus->card, "gusmem", gus, snd_gf1_mem_info_read);
|
snd_card_ro_proc_new(gus->card, "gusmem", gus, snd_gf1_mem_info_read);
|
||||||
|
|
Loading…
Reference in New Issue