From: Greg Kroah-Hartman Date: Tue, 8 Jul 2025 15:37:14 +0000 (+0200) Subject: 6.15-stable patches X-Git-Tag: v5.15.187~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=aa2b0b3eeb8cfb8b1dc49d1cbb2bcb294ffa251c;p=thirdparty%2Fkernel%2Fstable-queue.git 6.15-stable patches added patches: mm-vmalloc-fix-data-race-in-show_numa_info.patch --- diff --git a/queue-6.15/mm-vmalloc-fix-data-race-in-show_numa_info.patch b/queue-6.15/mm-vmalloc-fix-data-race-in-show_numa_info.patch new file mode 100644 index 0000000000..992b961d69 --- /dev/null +++ b/queue-6.15/mm-vmalloc-fix-data-race-in-show_numa_info.patch @@ -0,0 +1,164 @@ +From 5c5f0468d172ddec2e333d738d2a1f85402cf0bc Mon Sep 17 00:00:00 2001 +From: Jeongjun Park +Date: Fri, 9 May 2025 01:56:20 +0900 +Subject: mm/vmalloc: fix data race in show_numa_info() + +From: Jeongjun Park + +commit 5c5f0468d172ddec2e333d738d2a1f85402cf0bc upstream. + +The following data-race was found in show_numa_info(): + +================================================================== +BUG: KCSAN: data-race in vmalloc_info_show / vmalloc_info_show + +read to 0xffff88800971fe30 of 4 bytes by task 8289 on cpu 0: + show_numa_info mm/vmalloc.c:4936 [inline] + vmalloc_info_show+0x5a8/0x7e0 mm/vmalloc.c:5016 + seq_read_iter+0x373/0xb40 fs/seq_file.c:230 + proc_reg_read_iter+0x11e/0x170 fs/proc/inode.c:299 +.... + +write to 0xffff88800971fe30 of 4 bytes by task 8287 on cpu 1: + show_numa_info mm/vmalloc.c:4934 [inline] + vmalloc_info_show+0x38f/0x7e0 mm/vmalloc.c:5016 + seq_read_iter+0x373/0xb40 fs/seq_file.c:230 + proc_reg_read_iter+0x11e/0x170 fs/proc/inode.c:299 +.... + +value changed: 0x0000008f -> 0x00000000 +================================================================== + +According to this report,there is a read/write data-race because +m->private is accessible to multiple CPUs. To fix this, instead of +allocating the heap in proc_vmalloc_init() and passing the heap address to +m->private, vmalloc_info_show() should allocate the heap. + +Link: https://lkml.kernel.org/r/20250508165620.15321-1-aha310510@gmail.com +Fixes: 8e1d743f2c26 ("mm: vmalloc: support multiple nodes in vmallocinfo") +Signed-off-by: Jeongjun Park +Suggested-by: Eric Dumazet +Suggested-by: Andrew Morton +Reviewed-by: "Uladzislau Rezki (Sony)" +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/vmalloc.c | 63 ++++++++++++++++++++++++++++++++--------------------------- + 1 file changed, 35 insertions(+), 28 deletions(-) + +--- a/mm/vmalloc.c ++++ b/mm/vmalloc.c +@@ -3100,7 +3100,7 @@ static void clear_vm_uninitialized_flag( + /* + * Before removing VM_UNINITIALIZED, + * we should make sure that vm has proper values. +- * Pair with smp_rmb() in show_numa_info(). ++ * Pair with smp_rmb() in vread_iter() and vmalloc_info_show(). + */ + smp_wmb(); + vm->flags &= ~VM_UNINITIALIZED; +@@ -4934,28 +4934,29 @@ bool vmalloc_dump_obj(void *object) + #endif + + #ifdef CONFIG_PROC_FS +-static void show_numa_info(struct seq_file *m, struct vm_struct *v) +-{ +- if (IS_ENABLED(CONFIG_NUMA)) { +- unsigned int nr, *counters = m->private; +- unsigned int step = 1U << vm_area_page_order(v); + +- if (!counters) +- return; ++/* ++ * Print number of pages allocated on each memory node. ++ * ++ * This function can only be called if CONFIG_NUMA is enabled ++ * and VM_UNINITIALIZED bit in v->flags is disabled. ++ */ ++static void show_numa_info(struct seq_file *m, struct vm_struct *v, ++ unsigned int *counters) ++{ ++ unsigned int nr; ++ unsigned int step = 1U << vm_area_page_order(v); + +- if (v->flags & VM_UNINITIALIZED) +- return; +- /* Pair with smp_wmb() in clear_vm_uninitialized_flag() */ +- smp_rmb(); ++ if (!counters) ++ return; + +- memset(counters, 0, nr_node_ids * sizeof(unsigned int)); ++ memset(counters, 0, nr_node_ids * sizeof(unsigned int)); + +- for (nr = 0; nr < v->nr_pages; nr += step) +- counters[page_to_nid(v->pages[nr])] += step; +- for_each_node_state(nr, N_HIGH_MEMORY) +- if (counters[nr]) +- seq_printf(m, " N%u=%u", nr, counters[nr]); +- } ++ for (nr = 0; nr < v->nr_pages; nr += step) ++ counters[page_to_nid(v->pages[nr])] += step; ++ for_each_node_state(nr, N_HIGH_MEMORY) ++ if (counters[nr]) ++ seq_printf(m, " N%u=%u", nr, counters[nr]); + } + + static void show_purge_info(struct seq_file *m) +@@ -4983,6 +4984,10 @@ static int vmalloc_info_show(struct seq_ + struct vmap_area *va; + struct vm_struct *v; + int i; ++ unsigned int *counters; ++ ++ if (IS_ENABLED(CONFIG_NUMA)) ++ counters = kmalloc(nr_node_ids * sizeof(unsigned int), GFP_KERNEL); + + for (i = 0; i < nr_vmap_nodes; i++) { + vn = &vmap_nodes[i]; +@@ -4999,6 +5004,11 @@ static int vmalloc_info_show(struct seq_ + } + + v = va->vm; ++ if (v->flags & VM_UNINITIALIZED) ++ continue; ++ ++ /* Pair with smp_wmb() in clear_vm_uninitialized_flag() */ ++ smp_rmb(); + + seq_printf(m, "0x%pK-0x%pK %7ld", + v->addr, v->addr + v->size, v->size); +@@ -5033,7 +5043,9 @@ static int vmalloc_info_show(struct seq_ + if (is_vmalloc_addr(v->pages)) + seq_puts(m, " vpages"); + +- show_numa_info(m, v); ++ if (IS_ENABLED(CONFIG_NUMA)) ++ show_numa_info(m, v, counters); ++ + seq_putc(m, '\n'); + } + spin_unlock(&vn->busy.lock); +@@ -5043,19 +5055,14 @@ static int vmalloc_info_show(struct seq_ + * As a final step, dump "unpurged" areas. + */ + show_purge_info(m); ++ if (IS_ENABLED(CONFIG_NUMA)) ++ kfree(counters); + return 0; + } + + static int __init proc_vmalloc_init(void) + { +- void *priv_data = NULL; +- +- if (IS_ENABLED(CONFIG_NUMA)) +- priv_data = kmalloc(nr_node_ids * sizeof(unsigned int), GFP_KERNEL); +- +- proc_create_single_data("vmallocinfo", +- 0400, NULL, vmalloc_info_show, priv_data); +- ++ proc_create_single("vmallocinfo", 0400, NULL, vmalloc_info_show); + return 0; + } + module_init(proc_vmalloc_init); diff --git a/queue-6.15/series b/queue-6.15/series index 180456a7a2..4d971527a2 100644 --- a/queue-6.15/series +++ b/queue-6.15/series @@ -169,3 +169,4 @@ platform-x86-think-lmi-create-ksets-consecutively.patch platform-x86-think-lmi-fix-kobject-cleanup.patch platform-x86-think-lmi-fix-sysfs-group-cleanup.patch usb-typec-displayport-fix-potential-deadlock.patch +mm-vmalloc-fix-data-race-in-show_numa_info.patch