aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2011-11-22 10:02:02 -0500
committerPekka Enberg <penberg@kernel.org>2011-11-24 01:44:19 -0500
commitbc6697d8a506dedf09e8e9974ffa3a316183e608 (patch)
treeb54d3d45349fb8a00ce8a086da55a1ebf3394646 /mm
parent42d623a8cd08eb93ab221d22cee5a62618895bbf (diff)
slub: avoid potential NULL dereference or corruption
show_slab_objects() can trigger NULL dereferences or memory corruption. Another cpu can change its c->page to NULL or c->node to NUMA_NO_NODE while we use them. Use ACCESS_ONCE(c->page) and ACCESS_ONCE(c->node) to make sure this cannot happen. Acked-by: Christoph Lameter <cl@linux.com> Acked-by: David Rientjes <rientjes@google.com> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: Pekka Enberg <penberg@kernel.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/slub.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/mm/slub.c b/mm/slub.c
index 2a9cfd72a3d7..ed3334d9b6da 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -4444,30 +4444,31 @@ static ssize_t show_slab_objects(struct kmem_cache *s,
4444 4444
4445 for_each_possible_cpu(cpu) { 4445 for_each_possible_cpu(cpu) {
4446 struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu); 4446 struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
4447 int node = ACCESS_ONCE(c->node);
4447 struct page *page; 4448 struct page *page;
4448 4449
4449 if (!c || c->node < 0) 4450 if (node < 0)
4450 continue; 4451 continue;
4451 4452 page = ACCESS_ONCE(c->page);
4452 if (c->page) { 4453 if (page) {
4453 if (flags & SO_TOTAL) 4454 if (flags & SO_TOTAL)
4454 x = c->page->objects; 4455 x = page->objects;
4455 else if (flags & SO_OBJECTS) 4456 else if (flags & SO_OBJECTS)
4456 x = c->page->inuse; 4457 x = page->inuse;
4457 else 4458 else
4458 x = 1; 4459 x = 1;
4459 4460
4460 total += x; 4461 total += x;
4461 nodes[c->node] += x; 4462 nodes[node] += x;
4462 } 4463 }
4463 page = c->partial; 4464 page = c->partial;
4464 4465
4465 if (page) { 4466 if (page) {
4466 x = page->pobjects; 4467 x = page->pobjects;
4467 total += x; 4468 total += x;
4468 nodes[c->node] += x; 4469 nodes[node] += x;
4469 } 4470 }
4470 per_cpu[c->node]++; 4471 per_cpu[node]++;
4471 } 4472 }
4472 } 4473 }
4473 4474