Commit 84c1cf62465e2fb0a692620dcfeb52323ab03d48

Authored by Pekka Enberg
1 parent db210e70e5

SLUB: Fix merged slab cache names

As explained by Linus "I'm Proud to be an American" Torvalds:

  Looking at the merging code, I actually think it's totally
  buggy. If you have something like this:

   - load module A: create slab cache A

   - load module B: create slab cache B that can merge with A

   - unload module A

   - "cat /proc/slabinfo": BOOM. Oops.

  exactly because the name is not handled correctly, and you'll have
  module B holding open a slab cache that has a name pointer that points
  to module A that no longer exists.

This patch fixes the problem by using kstrdup() to allocate dynamic memory for
->name of "struct kmem_cache" as suggested by Christoph Lameter.

Acked-by: Christoph Lameter <cl@linux.com>
Cc: David Rientjes <rientjes@google.com>
Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Pekka Enberg <penberg@kernel.org>

Conflicts:

	mm/slub.c

Showing 1 changed file with 20 additions and 1 deletions Side-by-side Diff

... ... @@ -209,6 +209,7 @@
209 209 { return 0; }
210 210 static inline void sysfs_slab_remove(struct kmem_cache *s)
211 211 {
  212 + kfree(s->name);
212 213 kfree(s);
213 214 }
214 215  
... ... @@ -3169,6 +3170,16 @@
3169 3170 slab_state = UP;
3170 3171  
3171 3172 /* Provide the correct kmalloc names now that the caches are up */
  3173 + if (KMALLOC_MIN_SIZE <= 32) {
  3174 + kmalloc_caches[1]->name = kstrdup(kmalloc_caches[1]->name, GFP_NOWAIT);
  3175 + BUG_ON(!kmalloc_caches[1]->name);
  3176 + }
  3177 +
  3178 + if (KMALLOC_MIN_SIZE <= 64) {
  3179 + kmalloc_caches[2]->name = kstrdup(kmalloc_caches[2]->name, GFP_NOWAIT);
  3180 + BUG_ON(!kmalloc_caches[2]->name);
  3181 + }
  3182 +
3172 3183 for (i = KMALLOC_SHIFT_LOW; i < SLUB_PAGE_SHIFT; i++) {
3173 3184 char *s = kasprintf(GFP_NOWAIT, "kmalloc-%d", 1 << i);
3174 3185  
... ... @@ -3271,6 +3282,7 @@
3271 3282 size_t align, unsigned long flags, void (*ctor)(void *))
3272 3283 {
3273 3284 struct kmem_cache *s;
  3285 + char *n;
3274 3286  
3275 3287 if (WARN_ON(!name))
3276 3288 return NULL;
3277 3289  
3278 3290  
3279 3291  
... ... @@ -3294,19 +3306,25 @@
3294 3306 return s;
3295 3307 }
3296 3308  
  3309 + n = kstrdup(name, GFP_KERNEL);
  3310 + if (!n)
  3311 + goto err;
  3312 +
3297 3313 s = kmalloc(kmem_size, GFP_KERNEL);
3298 3314 if (s) {
3299   - if (kmem_cache_open(s, name,
  3315 + if (kmem_cache_open(s, n,
3300 3316 size, align, flags, ctor)) {
3301 3317 list_add(&s->list, &slab_caches);
3302 3318 if (sysfs_slab_add(s)) {
3303 3319 list_del(&s->list);
  3320 + kfree(n);
3304 3321 kfree(s);
3305 3322 goto err;
3306 3323 }
3307 3324 up_write(&slub_lock);
3308 3325 return s;
3309 3326 }
  3327 + kfree(n);
3310 3328 kfree(s);
3311 3329 }
3312 3330 up_write(&slub_lock);
... ... @@ -4439,6 +4457,7 @@
4439 4457 {
4440 4458 struct kmem_cache *s = to_slab(kobj);
4441 4459  
  4460 + kfree(s->name);
4442 4461 kfree(s);
4443 4462 }
4444 4463