Skip to content

Commit

Permalink
slub: avoid leaking caches or refcounts on sysfs error
Browse files Browse the repository at this point in the history
If a slab cache is mergeable and the sysfs alias cannot be added, the
target cache shall have its refcount decremented.  kmem_cache_create()
will return NULL, so if kmem_cache_destroy() is ever called on the target
cache, it will never be freed if the refcount has been leaked.

Likewise, if a slab cache is not mergeable and the sysfs link cannot be
added, the new cache shall be removed from the slab_caches list.
kmem_cache_create() will return NULL, so it will be impossible to call
kmem_cache_destroy() on it.

Both of these operations require slub_lock since refcount of all slab
caches and slab_caches are protected by the lock.

In the mergeable case, it would be better to restore objsize and offset
back to their original values, but this could race with another merge
since slub_lock was dropped.

Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: David Rientjes <rientjes@google.com>
Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
  • Loading branch information
David Rientjes authored and Pekka Enberg committed Dec 29, 2008
1 parent dfcd361 commit 7b8f3b6
Showing 1 changed file with 11 additions and 2 deletions.
13 changes: 11 additions & 2 deletions mm/slub.c
Original file line number Diff line number Diff line change
Expand Up @@ -3124,8 +3124,12 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *)));
up_write(&slub_lock);

if (sysfs_slab_alias(s, name))
if (sysfs_slab_alias(s, name)) {
down_write(&slub_lock);
s->refcount--;
up_write(&slub_lock);
goto err;
}
return s;
}

Expand All @@ -3135,8 +3139,13 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
size, align, flags, ctor)) {
list_add(&s->list, &slab_caches);
up_write(&slub_lock);
if (sysfs_slab_add(s))
if (sysfs_slab_add(s)) {
down_write(&slub_lock);
list_del(&s->list);
up_write(&slub_lock);
kfree(s);
goto err;
}
return s;
}
kfree(s);
Expand Down

0 comments on commit 7b8f3b6

Please sign in to comment.