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

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>

authored by

Dave Jones and committed by
Linus Torvalds
54b6a731 9a41707b

+15 -14
+15 -14
mm/slub.c
··· 5214 5214 5215 5215 s->kobj.kset = cache_kset(s); 5216 5216 err = kobject_init_and_add(&s->kobj, &slab_ktype, NULL, "%s", name); 5217 - if (err) { 5218 - kobject_put(&s->kobj); 5219 - return err; 5220 - } 5217 + if (err) 5218 + goto out_put_kobj; 5221 5219 5222 5220 err = sysfs_create_group(&s->kobj, &slab_attr_group); 5223 - if (err) { 5224 - kobject_del(&s->kobj); 5225 - kobject_put(&s->kobj); 5226 - return err; 5227 - } 5221 + if (err) 5222 + goto out_del_kobj; 5228 5223 5229 5224 #ifdef CONFIG_MEMCG_KMEM 5230 5225 if (is_root_cache(s)) { 5231 5226 s->memcg_kset = kset_create_and_add("cgroup", NULL, &s->kobj); 5232 5227 if (!s->memcg_kset) { 5233 - kobject_del(&s->kobj); 5234 - kobject_put(&s->kobj); 5235 - return -ENOMEM; 5228 + err = -ENOMEM; 5229 + goto out_del_kobj; 5236 5230 } 5237 5231 } 5238 5232 #endif ··· 5235 5241 if (!unmergeable) { 5236 5242 /* Setup first alias */ 5237 5243 sysfs_slab_alias(s, s->name); 5238 - kfree(name); 5239 5244 } 5240 - return 0; 5245 + out: 5246 + if (!unmergeable) 5247 + kfree(name); 5248 + return err; 5249 + out_del_kobj: 5250 + kobject_del(&s->kobj); 5251 + out_put_kobj: 5252 + kobject_put(&s->kobj); 5253 + goto out; 5241 5254 } 5242 5255 5243 5256 static void sysfs_slab_remove(struct kmem_cache *s)