slub: fix leak of 'name' in sysfs_slab_add

The failure paths of sysfs_slab_add don't release the allocation of
'name' made by create_unique_id() a few lines above the context of the
diff below.  Create a common exit path to make it more obvious what
needs freeing.

[vdavydov@parallels.com: free the name only if !unmergeable]
Signed-off-by: Dave Jones <davej@fedoraproject.org>
Signed-off-by: Vladimir Davydov <vdavydov@parallels.com>
Cc: Pekka Enberg <penberg@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Dave Jones 2014-04-07 15:39:32 -07:00 committed by Linus Torvalds
parent 9a41707bd3
commit 54b6a73102

View File

@ -5214,25 +5214,19 @@ static int sysfs_slab_add(struct kmem_cache *s)
s->kobj.kset = cache_kset(s); s->kobj.kset = cache_kset(s);
err = kobject_init_and_add(&s->kobj, &slab_ktype, NULL, "%s", name); err = kobject_init_and_add(&s->kobj, &slab_ktype, NULL, "%s", name);
if (err) { if (err)
kobject_put(&s->kobj); goto out_put_kobj;
return err;
}
err = sysfs_create_group(&s->kobj, &slab_attr_group); err = sysfs_create_group(&s->kobj, &slab_attr_group);
if (err) { if (err)
kobject_del(&s->kobj); goto out_del_kobj;
kobject_put(&s->kobj);
return err;
}
#ifdef CONFIG_MEMCG_KMEM #ifdef CONFIG_MEMCG_KMEM
if (is_root_cache(s)) { if (is_root_cache(s)) {
s->memcg_kset = kset_create_and_add("cgroup", NULL, &s->kobj); s->memcg_kset = kset_create_and_add("cgroup", NULL, &s->kobj);
if (!s->memcg_kset) { if (!s->memcg_kset) {
kobject_del(&s->kobj); err = -ENOMEM;
kobject_put(&s->kobj); goto out_del_kobj;
return -ENOMEM;
} }
} }
#endif #endif
@ -5241,9 +5235,16 @@ static int sysfs_slab_add(struct kmem_cache *s)
if (!unmergeable) { if (!unmergeable) {
/* Setup first alias */ /* Setup first alias */
sysfs_slab_alias(s, s->name); sysfs_slab_alias(s, s->name);
kfree(name);
} }
return 0; out:
if (!unmergeable)
kfree(name);
return err;
out_del_kobj:
kobject_del(&s->kobj);
out_put_kobj:
kobject_put(&s->kobj);
goto out;
} }
static void sysfs_slab_remove(struct kmem_cache *s) static void sysfs_slab_remove(struct kmem_cache *s)