Commit d2e7b7d0aa021847c59f882b066e7d3812902870

Authored by Siddha, Suresh B
Committed by Linus Torvalds
1 parent 980128f223

[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

... ... @@ -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