From: Hailong Liu <hailong.liu@oppo.com>
To: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>,
"surenb@google.com" <surenb@google.com>,
"Liam.Howlett@oracle.com" <Liam.Howlett@oracle.com>,
"akpm@linux-foundation.org" <akpm@linux-foundation.org>
Cc: "黄朝阳 (Zhaoyang Huang)" <zhaoyang.huang@unisoc.com>,
"zhangpeng.00@bytedance.com" <zhangpeng.00@bytedance.com>,
"linux-mm@kvack.org" <linux-mm@kvack.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: [bug] [stable-6.6.66] [maple_tree] [mmap] mab_mas_cp+0xb0/0x278 invalid maple_state for spanning
Date: Mon, 28 Apr 2025 22:34:06 +0800 [thread overview]
Message-ID: <1652f7eb-a51b-4fee-8058-c73af63bacd1@oppo.com> (raw)
[-- 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);
next reply other threads:[~2025-04-28 14:34 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-28 14:34 Hailong Liu [this message]
2025-04-28 18:12 ` Liam R. Howlett
2025-04-28 19:26 ` Hailong Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1652f7eb-a51b-4fee-8058-c73af63bacd1@oppo.com \
--to=hailong.liu@oppo.com \
--cc=Liam.Howlett@oracle.com \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=lorenzo.stoakes@oracle.com \
--cc=surenb@google.com \
--cc=zhangpeng.00@bytedance.com \
--cc=zhaoyang.huang@unisoc.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox