Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Eric Dumazet and committed by
Pekka Enberg
bc6697d8 42d623a8

+11 -10
+11 -10
mm/slub.c
··· 4444 4444 4445 4445 for_each_possible_cpu(cpu) { 4446 4446 struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu); 4447 + int node = ACCESS_ONCE(c->node); 4447 4448 struct page *page; 4448 4449 4449 - if (!c || c->node < 0) 4450 + if (node < 0) 4450 4451 continue; 4451 - 4452 - if (c->page) { 4453 - if (flags & SO_TOTAL) 4454 - x = c->page->objects; 4452 + page = ACCESS_ONCE(c->page); 4453 + if (page) { 4454 + if (flags & SO_TOTAL) 4455 + x = page->objects; 4455 4456 else if (flags & SO_OBJECTS) 4456 - x = c->page->inuse; 4457 + x = page->inuse; 4457 4458 else 4458 4459 x = 1; 4459 4460 4460 4461 total += x; 4461 - nodes[c->node] += x; 4462 + nodes[node] += x; 4462 4463 } 4463 4464 page = c->partial; 4464 4465 4465 4466 if (page) { 4466 4467 x = page->pobjects; 4467 - total += x; 4468 - nodes[c->node] += x; 4468 + total += x; 4469 + nodes[node] += x; 4469 4470 } 4470 - per_cpu[c->node]++; 4471 + per_cpu[node]++; 4471 4472 } 4472 4473 } 4473 4474