Commit 84c1cf62465e2fb0a692620dcfeb52323ab03d48
1 parent
db210e70e5
Exists in
master
and in
7 other branches
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
mm/slub.c
... | ... | @@ -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 |