diff options
author | Dave Jones <davej@fedoraproject.org> | 2014-04-07 18:39:32 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-07 19:36:13 -0400 |
commit | 54b6a731025f9528d44945a72b1f4e5946bb2d80 (patch) | |
tree | 7db33948c9ab6fb39b31d275185e0ce55315ac03 /mm | |
parent | 9a41707bd3a0811919000daf094e9d50ea65f7da (diff) |
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>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/slub.c | 29 |
1 files changed, 15 insertions, 14 deletions
@@ -5214,25 +5214,19 @@ static int sysfs_slab_add(struct kmem_cache *s) | |||
5214 | 5214 | ||
5215 | s->kobj.kset = cache_kset(s); | 5215 | s->kobj.kset = cache_kset(s); |
5216 | err = kobject_init_and_add(&s->kobj, &slab_ktype, NULL, "%s", name); | 5216 | err = kobject_init_and_add(&s->kobj, &slab_ktype, NULL, "%s", name); |
5217 | if (err) { | 5217 | if (err) |
5218 | kobject_put(&s->kobj); | 5218 | goto out_put_kobj; |
5219 | return err; | ||
5220 | } | ||
5221 | 5219 | ||
5222 | err = sysfs_create_group(&s->kobj, &slab_attr_group); | 5220 | err = sysfs_create_group(&s->kobj, &slab_attr_group); |
5223 | if (err) { | 5221 | if (err) |
5224 | kobject_del(&s->kobj); | 5222 | goto out_del_kobj; |
5225 | kobject_put(&s->kobj); | ||
5226 | return err; | ||
5227 | } | ||
5228 | 5223 | ||
5229 | #ifdef CONFIG_MEMCG_KMEM | 5224 | #ifdef CONFIG_MEMCG_KMEM |
5230 | if (is_root_cache(s)) { | 5225 | if (is_root_cache(s)) { |
5231 | s->memcg_kset = kset_create_and_add("cgroup", NULL, &s->kobj); | 5226 | s->memcg_kset = kset_create_and_add("cgroup", NULL, &s->kobj); |
5232 | if (!s->memcg_kset) { | 5227 | if (!s->memcg_kset) { |
5233 | kobject_del(&s->kobj); | 5228 | err = -ENOMEM; |
5234 | kobject_put(&s->kobj); | 5229 | goto out_del_kobj; |
5235 | return -ENOMEM; | ||
5236 | } | 5230 | } |
5237 | } | 5231 | } |
5238 | #endif | 5232 | #endif |
@@ -5241,9 +5235,16 @@ static int sysfs_slab_add(struct kmem_cache *s) | |||
5241 | if (!unmergeable) { | 5235 | if (!unmergeable) { |
5242 | /* Setup first alias */ | 5236 | /* Setup first alias */ |
5243 | sysfs_slab_alias(s, s->name); | 5237 | sysfs_slab_alias(s, s->name); |
5244 | kfree(name); | ||
5245 | } | 5238 | } |
5246 | return 0; | 5239 | out: |
5240 | if (!unmergeable) | ||
5241 | kfree(name); | ||
5242 | return err; | ||
5243 | out_del_kobj: | ||
5244 | kobject_del(&s->kobj); | ||
5245 | out_put_kobj: | ||
5246 | kobject_put(&s->kobj); | ||
5247 | goto out; | ||
5247 | } | 5248 | } |
5248 | 5249 | ||
5249 | static void sysfs_slab_remove(struct kmem_cache *s) | 5250 | static void sysfs_slab_remove(struct kmem_cache *s) |