Commit d2e7b7d0aa021847c59f882b066e7d3812902870
Committed by
Linus Torvalds
1 parent
980128f223
Exists in
master
and in
7 other branches
[PATCH] fix potential stack overflow in mm/slab.c
On High end systems (1024 or so cpus) this can potentially cause stack overflow. Fix the stack usage. Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 1 changed file with 14 additions and 9 deletions Side-by-side Diff
mm/slab.c
... | ... | @@ -3725,22 +3725,26 @@ |
3725 | 3725 | static int do_tune_cpucache(struct kmem_cache *cachep, int limit, |
3726 | 3726 | int batchcount, int shared) |
3727 | 3727 | { |
3728 | - struct ccupdate_struct new; | |
3728 | + struct ccupdate_struct *new; | |
3729 | 3729 | int i; |
3730 | 3730 | |
3731 | - memset(&new.new, 0, sizeof(new.new)); | |
3731 | + new = kzalloc(sizeof(*new), GFP_KERNEL); | |
3732 | + if (!new) | |
3733 | + return -ENOMEM; | |
3734 | + | |
3732 | 3735 | for_each_online_cpu(i) { |
3733 | - new.new[i] = alloc_arraycache(cpu_to_node(i), limit, | |
3736 | + new->new[i] = alloc_arraycache(cpu_to_node(i), limit, | |
3734 | 3737 | batchcount); |
3735 | - if (!new.new[i]) { | |
3738 | + if (!new->new[i]) { | |
3736 | 3739 | for (i--; i >= 0; i--) |
3737 | - kfree(new.new[i]); | |
3740 | + kfree(new->new[i]); | |
3741 | + kfree(new); | |
3738 | 3742 | return -ENOMEM; |
3739 | 3743 | } |
3740 | 3744 | } |
3741 | - new.cachep = cachep; | |
3745 | + new->cachep = cachep; | |
3742 | 3746 | |
3743 | - on_each_cpu(do_ccupdate_local, (void *)&new, 1, 1); | |
3747 | + on_each_cpu(do_ccupdate_local, (void *)new, 1, 1); | |
3744 | 3748 | |
3745 | 3749 | check_irq_on(); |
3746 | 3750 | cachep->batchcount = batchcount; |
... | ... | @@ -3748,7 +3752,7 @@ |
3748 | 3752 | cachep->shared = shared; |
3749 | 3753 | |
3750 | 3754 | for_each_online_cpu(i) { |
3751 | - struct array_cache *ccold = new.new[i]; | |
3755 | + struct array_cache *ccold = new->new[i]; | |
3752 | 3756 | if (!ccold) |
3753 | 3757 | continue; |
3754 | 3758 | spin_lock_irq(&cachep->nodelists[cpu_to_node(i)]->list_lock); |
... | ... | @@ -3756,7 +3760,7 @@ |
3756 | 3760 | spin_unlock_irq(&cachep->nodelists[cpu_to_node(i)]->list_lock); |
3757 | 3761 | kfree(ccold); |
3758 | 3762 | } |
3759 | - | |
3763 | + kfree(new); | |
3760 | 3764 | return alloc_kmemlist(cachep); |
3761 | 3765 | } |
3762 | 3766 | |
... | ... | @@ -4274,6 +4278,7 @@ |
4274 | 4278 | show_symbol(m, n[2*i+2]); |
4275 | 4279 | seq_putc(m, '\n'); |
4276 | 4280 | } |
4281 | + | |
4277 | 4282 | return 0; |
4278 | 4283 | } |
4279 | 4284 |