linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [bug] [stable-6.6.66] [maple_tree] [mmap] mab_mas_cp+0xb0/0x278 invalid maple_state for spanning
@ 2025-04-28 14:34 Hailong Liu
  2025-04-28 18:12 ` Liam R. Howlett
  0 siblings, 1 reply; 3+ messages in thread
From: Hailong Liu @ 2025-04-28 14:34 UTC (permalink / raw)
  To: Lorenzo Stoakes, surenb, Liam.Howlett, akpm
  Cc: 黄朝阳 (Zhaoyang Huang),
	zhangpeng.00, linux-mm, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 3546 bytes --]

Hi:

After upgrade to kernel-6.6-y we face a panic on vma_merge()

Unable to handle kernel NULL pointer dereference at virtual address 0000000000000078
Mem abort info:
  ESR = 0x0000000096000006
  EC = 0x25: DABT (current EL), IL = 32 bits
  SET = 0, FnV = 0
  EA = 0, S1PTW = 0
  FSC = 0x06: level 2 translation fault
Data abort info:
  ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
  CM = 0, WnR = 0, TnD = 0, TagAccess = 0
  GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
user pgtable: 4k pages, 39-bit VAs, pgdp=0000000a381d0000
[0000000000000078] pgd=0800000a381d1003, p4d=0800000a381d1003, pud=0800000a381d1003, pmd=0000000000000000
Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP
Skip md ftrace buffer dump for: 0x1609e0
CPU: 7 PID: 11563 Comm: x Tainted: G        W  OE      6.6.56-android15
Hardware name: Qualcomm Technologies, Inc. Parrot QRD, Alpha-M (DT)
pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : mab_mas_cp+0xb0/0x278
lr : mas_spanning_rebalance+0x830/0xeb4
sp : ffffffc0b2323410
x29: ffffffc0b2323420 x28: 0000000000000009 x27: 0000000000000001
x26: ffffff804c0ddb0c x25: 0000000000000001 x24: 0000000000000008
x23: 000000000000000c x22: 000000000000000c x21: ffffffc0b23236d0
x20: 0000000000000000 x19: ffffffc0b2323690 x18: ffffffc0ac5a2088
x17: 0000000000000000 x16: ffffff89b7d68d48 x15: ffffff897cfb6898
x14: ffffff89ca568000 x13: ffffff88082e74b0 x12: 0000000000000000
x11: 000000000000000f x10: 0000000000000080 x9 : 000000000000000d
x8 : 000000000000000d x7 : ffffff89d16690c8 x6 : ffffff87b3847bb8
x5 : ffffff804c0ddbe8 x4 : 0000000000000000 x3 : ffffffc0b23234c8
x2 : 0000000000000019 x1 : 000000000000000d x0 : 0000000000000080
Call trace:
 mab_mas_cp+0xb0/0x278
 mas_spanning_rebalance+0x830/0xeb4
 mas_wr_spanning_store+0x8ac/0xa58
 mas_wr_store_entry+0x130/0x180
 mas_store_prealloc+0x98/0x1bc
 vma_iter_store+0x64/0x74
 vma_merge+0x5e4/0x73c
 mmap_region+0x8d8/0xa30
 do_mmap+0x3e0/0x578
 vm_mmap_pgoff+0x1a0/0x1f8
 ksys_mmap_pgoff+0x78/0xf4
 __arm64_sys_mmap+0x34/0x44
 invoke_syscall+0x58/0x114
 el0_svc_common+0x80/0xe0
 do_el0_svc+0x1c/0x28
 el0_svc+0x38/0x68
 el0t_64_sync_handler+0x68/0xbc
 el0t_64_sync+0x1a8/0x1ac

the issue introduced by bdc136e2b05f ("mm: resolve faulty mmap_region() error path behaviour")

the reason is that call vma_iter_prealloc() twice and the maple_state is invalid. I write a reproducer here
by cat /proc/maple_test_merge the patch in attachment(maple_tree_debug.patch).

the reproducer simulates vma mmap at frist. then mmap_region() vma_merge(), 

the code from stable-6.6.y
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/tree/mm/mmap.c?h=linux-6.6.y

the reason show as follows
maple_tree
               parent
    leaf_1(..|c)   leaf_2(d..f|..)

__mmap_region(addr=d)
    1. vma_iter_prealloc()
        mas_state node=leaf_2 alloc=*mt_alloc_one* new_node_a

    2. mmap_file(file, vma)
        the vm_flags changed by some driver (ashmem) https://android.googlesource.com/kernel/msm/+/android-6.0.1_r0.74/drivers/staging/android/ashmem.c#312

vma_merge() (c can merge with d)
    3. vma_prev()
        mas_state node=leaf_1 alloc=new_node_a
    5. vma_iter_config()
        mas_state node=parent alloc=new_node_a
    4. vma_iter_prealloc()
        mas_state node=parent alloc=new_node_a
    6. vma_iter_store() --> panic
        use invalid new_node_a for spanning write


IMO, this issue can be fixed by mmap side maybe conflict with the patch. if
fix in maple_tree which need to destory the new_node_a


Brs,
Hailong.

[-- Attachment #2: maple_tree_debug.patch --]
[-- Type: text/plain, Size: 6326 bytes --]

diff --git a/mm/mmap.c b/mm/mmap.c
index 6df3e778e749..f6dd36674ab3 100755
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -49,6 +49,7 @@
 #include <linux/oom.h>
 #include <linux/sched/mm.h>
 #include <linux/ksm.h>
+#include <linux/proc_fs.h>
 
 #include <linux/uaccess.h>
 #include <asm/cacheflush.h>
@@ -3955,11 +3956,172 @@ static int reserve_mem_notifier(struct notifier_block *nb,
 	return NOTIFY_OK;
 }
 
+static void vmi_iter_initialize(struct vma_iterator *vmi, struct mm_struct *mm,
+				unsigned long start)
+{
+	struct ma_state *mas = &vmi->mas;
+
+	memset(vmi, 0, sizeof(*vmi));
+	mas->tree = &mm->mm_mt;
+	mas->index = start;
+	mas->node = MAS_START;
+}
+
+static void dump_mt_vma(struct vm_area_struct *vma)
+{
+	pr_info("[VMA]: [0x%10lx-0x%10lx]\n", vma->vm_start, vma->vm_end);
+}
+
+struct snapshot_vma {
+	unsigned long vm_start, vm_end, entry;
+};
+
+struct snapshot_vma snapshot_vmas[] = {
+	{ 0x0000000000, 0x0000ffffff, 0x0000000000000000 },
+	{ 0x0001000000, 0x0001000fff, 0xffffff8008c35c80 },
+	{ 0x0001001000, 0x0001001fff, 0xffffff8008c354b0 },
+	{ 0x0001002000, 0x0001002fff, 0xffffff800a17d3e8 },
+	{ 0x0001003000, 0x0001003fff, 0xffffff800a17d898 },
+	{ 0x0001004000, 0x0001004fff, 0xffffff800a17daf0 },
+	{ 0x0001005000, 0x0001005fff, 0xffffff800a17d708 },
+	{ 0x0001006000, 0x0001006fff, 0xffffff800a17d7d0 },
+	{ 0x0001007000, 0x0001007fff, 0xffffff800a17d320 },
+	{ 0x0001008000, 0x0001008fff, 0xffffff800a17d578 },
+	{ 0x0001009000, 0x0001009fff, 0xffffff800a17d258 },
+	{ 0x000100a000, 0x000100afff, 0xffffff800a17de10 },
+	{ 0x000100b000, 0x000100bfff, 0xffffff800a17dbb8 },
+	{ 0x000100c000, 0x000100cfff, 0xffffff800a17d190 },
+	/* merge_prev index 15 */
+	{ 0x000100d000, 0x000100dfff, 0xffffff800a17ded8 },
+	/* index 16 */
+	{ 0x000100e000, 0x5580a2ffff, 0x0000000000000000 },
+	{ 0x5580a30000, 0x5580a30fff, 0xffffff8008c353e8 },
+	{ 0x5580a31000, 0x5580a4efff, 0x0000000000000000 },
+	{ 0x5580a4f000, 0x5580a4ffff, 0xffffff8008c350c8 },
+	{ 0x5580a50000, 0x5580a50fff, 0xffffff8008c35ed8 },
+	{ 0x5580a51000, 0x5580c4afff, 0x0000000000000000 },
+	{ 0x5580c4b000, 0x5580c6bfff, 0xffffff8008c35708 },
+	{ 0x5580c6c000, 0x7f880cffff, 0x0000000000000000 },
+	{ 0x7f880d0000, 0x7f88257fff, 0xffffff8008d80000 },
+	{ 0x7f88258000, 0x7f8826bfff, 0xffffff8008d807d0 },
+	{ 0x7f8826c000, 0x7f8826ffff, 0xffffff8008c904b0 },
+	{ 0x7f88270000, 0x7f88271fff, 0xffffff8008c90bb8 },
+	{ 0x7f88272000, 0x7f8827efff, 0xffffff8008c90578 },
+	{ 0x7f8827f000, 0x7f8827ffff, 0x0000000000000000 },
+	{ 0x7f88280000, 0x7f88293fff, 0xffffff8008c4aa28 },
+	{ 0x7f88294000, 0x7f882aefff, 0xffffff8008c4a4b0 },
+	{ 0x7f882af000, 0x7f882affff, 0xffffff8008c35a28 },
+	{ 0x7f882b0000, 0x7f882b0fff, 0xffffff8008c903e8 },
+	{ 0x7f882b1000, 0x7f882bffff, 0x0000000000000000 },
+	{ 0x7f882c0000, 0x7f8833ffff, 0xffffff8008c35d48 },
+	{ 0x7f88340000, 0x7f8834efff, 0xffffff8008c35000 },
+	{ 0x7f8834f000, 0x7f8834ffff, 0xffffff8008c35640 },
+	{ 0x7f88350000, 0x7f88350fff, 0xffffff8008c907d0 },
+	{ 0x7f88351000, 0x7f8835ffff, 0x0000000000000000 },
+	{ 0x7f88360000, 0x7f8855afff, 0xffffff8008c35af0 },
+	{ 0x7f8855b000, 0x7f88564fff, 0xffffff8008c35320 },
+	{ 0x7f88565000, 0x7f8856ffff, 0xffffff8008c35190 },
+	{ 0x7f88570000, 0x7f88572fff, 0xffffff8008c90708 },
+	{ 0x7f88573000, 0x7f88575fff, 0xffffff8008c357d0 },
+	{ 0x7f88576000, 0x7f88584fff, 0x0000000000000000 },
+	{ 0x7f88585000, 0x7f885abfff, 0xffffff8008c35bb8 },
+	{ 0x7f885ac000, 0x7f885b3fff, 0x0000000000000000 },
+	{ 0x7f885b4000, 0x7f885b7fff, 0xffffff8008c90d48 },
+	{ 0x7f885b8000, 0x7f885bdfff, 0x0000000000000000 },
+	{ 0x7f885be000, 0x7f885bffff, 0xffffff8008c35258 },
+	{ 0x7f885c0000, 0x7f885c1fff, 0xffffff8008c35578 },
+	{ 0x7f885c2000, 0x7f885c2fff, 0xffffff8008c35898 },
+	{ 0x7f885c3000, 0x7f885c4fff, 0xffffff8008c35e10 },
+	{ 0x7f885c5000, 0x7f885c6fff, 0xffffff8008c35960 },
+	{ 0x7f885c7000, 0x7fda32bfff, 0x0000000000000000 },
+	{ 0x7fda32c000, 0x7fda34cfff, 0xffffff800940dc80 },
+	{ 0x7fda34d000, 0xffffffffffffff, 0000000000000000 },
+};
+
+#define MERGE_INX (15)
+static int maple_test_merge_proc_show(struct seq_file *m, void *v)
+{
+	struct vma_iterator vmi;
+	struct mm_struct *mm;
+	struct snapshot_vma *snapshot_vma;
+	struct vm_area_struct *vmas, *vma, *prev_vma;
+	int snapshot_len = ARRAY_SIZE(snapshot_vmas);
+	int i;
+
+	mm = kmalloc(sizeof(*mm), GFP_KERNEL | __GFP_NOFAIL);
+	vmas = kmalloc_array(snapshot_len, sizeof(struct vm_area_struct),
+			     GFP_KERNEL | __GFP_NOFAIL);
+	BUG_ON(!mm || !vmas);
+	mt_init_flags(&mm->mm_mt, MM_MT_FLAGS);
+
+	for (i = 0; i < snapshot_len; i++) {
+		snapshot_vma = snapshot_vmas + i;
+		vma = vmas + i;
+		/* gap */
+		if (!snapshot_vma->entry)
+			continue;
+
+		vma->vm_start = snapshot_vma->vm_start;
+		vma->vm_end = snapshot_vma->vm_end + 1;
+
+		/* mma_region */
+		vmi_iter_initialize(&vmi, mm, vma->vm_start);
+		vma_iter_config(&vmi, vma->vm_start, vma->vm_end);
+		if (vma_iter_prealloc(&vmi, vma))
+			BUG_ON(true);
+		vma_iter_store(&vmi, vma);
+	}
+
+	/*
+	 * 1. mock __mmap_region()
+	 * the new_vma: [0x100e000-0x100f000]
+	 */
+	snapshot_vma = snapshot_vmas + MERGE_INX;
+	vma->vm_start = snapshot_vma->vm_start;
+	vma->vm_end = snapshot_vma->vm_start + 0x1000;
+	dump_mt_vma(vma);
+	vmi_iter_initialize(&vmi, mm, vma->vm_start);
+	vma_iter_config(&vmi, vma->vm_start, vma->vm_end);
+
+	/*
+	 * 2. mock vma_iter_prealloc()
+	 * in __mmap_region()
+	 */
+	if (vma_iter_prealloc(&vmi, vma))
+		BUG_ON(true);
+
+	/*
+	 * 3. mock vma_merge()
+	 * the new_vma can be merged with prev_vma [0x100d000-0x100e000]
+	 */
+	prev_vma = vma_prev(&vmi);
+	prev_vma->vm_end = vma->vm_end;
+	dump_mt_vma(prev_vma);
+	vma_iter_config(&vmi, prev_vma->vm_start, prev_vma->vm_end);
+
+	/*
+	 * 4. mock vma_iter_prealloc()
+	 * in vma_merge();
+	 */
+	if (vma_iter_prealloc(&vmi, prev_vma))
+		BUG_ON(true);
+
+	/*
+	 * 5. panic here
+	 */
+	vma_iter_store(&vmi, prev_vma);
+	__mt_destroy(&mm->mm_mt);
+	kfree(mm);
+	kfree(vmas);
+	return 0;
+}
+
 static int __meminit init_reserve_notifier(void)
 {
 	if (hotplug_memory_notifier(reserve_mem_notifier, DEFAULT_CALLBACK_PRI))
 		pr_err("Failed registering memory add/remove notifier for admin reserve\n");
 
+	proc_create_single("maple_test_merge", 0, NULL, maple_test_merge_proc_show);
 	return 0;
 }
 subsys_initcall(init_reserve_notifier);

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-04-28 19:26 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-04-28 14:34 [bug] [stable-6.6.66] [maple_tree] [mmap] mab_mas_cp+0xb0/0x278 invalid maple_state for spanning Hailong Liu
2025-04-28 18:12 ` Liam R. Howlett
2025-04-28 19:26   ` Hailong Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox