Re: [PATCH v3 4/7] mm/mremap: initial refactor of move_vma()

From: Lorenzo Stoakes
Date: Sun Mar 30 2025 - 12:47:21 EST


On Sun, Mar 30, 2025 at 11:01:16PM +0800, Lai, Yi wrote:
> On Mon, Mar 10, 2025 at 08:50:37PM +0000, Lorenzo Stoakes wrote:
> > Update move_vma() to use the threaded VRM object, de-duplicate code and
> > separate into smaller functions to aid readability and debug-ability.

[snip]
>
>
> Hi Lorenzo Stoakes,
>
> Greetings!
>
> I used Syzkaller and found that there is general protection fault in mremap in linux-next tag - next-20250325.
>
> After bisection and the first bad commit is:
> "
> d5c8aec0542e mm/mremap: initial refactor of move_vma()
> "
>
> The deadlock can still be reproduced. You could try following reproduction binary.

Thanks. Yes the repro is consistent, and I've identified the problem.

To make life easier as this is noisy, I'll send a fixpatch in reply to this
separately.

>
> All detailed into can be found at:
> https://github.com/laifryiee/syzkaller_logs/tree/main/250329_061207_mremap
> Syzkaller repro code:
> https://github.com/laifryiee/syzkaller_logs/tree/main/250329_061207_mremap/repro.c
> Syzkaller repro syscall steps:
> https://github.com/laifryiee/syzkaller_logs/tree/main/250329_061207_mremap/repro.prog
> Syzkaller report:
> https://github.com/laifryiee/syzkaller_logs/tree/main/250329_061207_mremap/repro.report
> Kconfig(make olddefconfig):
> https://github.com/laifryiee/syzkaller_logs/tree/main/250329_061207_mremap/kconfig_origin
> Bisect info:
> https://github.com/laifryiee/syzkaller_logs/tree/main/250329_061207_mremap/bisect_info.log
> bzImage:
> https://github.com/laifryiee/syzkaller_logs/raw/refs/heads/main/250329_061207_mremap/bzImage_eb4bc4b07f66f01618d9cb1aa4eaef59b1188415
> Issue dmesg:
> https://github.com/laifryiee/syzkaller_logs/blob/main/250329_061207_mremap/eb4bc4b07f66f01618d9cb1aa4eaef59b1188415_dmesg.log
>
> "
> [ 43.795673] Oops: general protection fault, probably for non-canonical address 0xdffffc0000000004: 0000 [#1] SMP KASI
> [ 43.797814] KASAN: null-ptr-deref in range [0x0000000000000020-0x0000000000000027]
> [ 43.799835] CPU: 1 UID: 0 PID: 665 Comm: repro Not tainted 6.14.0-next-20250325-eb4bc4b07f66 #1 PREEMPT(voluntary)
> [ 43.800338] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org4
> [ 43.800911] RIP: 0010:__do_sys_mremap+0x13a9/0x15d0

This is in vrm_uncharge():

At:

if (!(vrm->vma->vm_flags & VM_ACCOUNT))
return;

Here, vrm->vma is NULL.

This is being called by expand_vma_in_place():

vma = vrm->vma = vma_merge_extend(&vmi, vma, vrm->delta);
if (!vma) {
vrm_uncharge(vrm); <--- here
return -ENOMEM;
}

Now the astute reader might notice a rather silly mistake here... we are
assigning both vma and vrm->vma to the result of vma_merge_extend(), then
seeing if vma is NULL, then trying to access vrm->vma...

So fix is to correct that and reassign vrm->vma only afterwards (a failed
merge will not result in vrm->vma being invalidated).

Cheers, Lorenzo

> [ 43.801188] Code: e8 ac 57 a8 ff 48 8b 85 30 fe ff ff 48 89 83 70 ff ff ff 49 89 c5 e9 2b f2 ff ff e8 91 57 a8 ff 485
> [ 43.802152] RSP: 0018:ffff88801aa67ce8 EFLAGS: 00010293
> [ 43.802432] RAX: dffffc0000000004 RBX: ffff88801aa67eb0 RCX: ffffffff81e42e5a
> [ 43.802791] RDX: ffff888011e6ca80 RSI: ffffffff81df64cf RDI: 0000000000000007
> [ 43.803172] RBP: ffff88801aa67ed8 R08: 0000000000000000 R09: ffffed10023cd950
> [ 43.803558] R10: 0000000010000000 R11: ffff888011e6d8d8 R12: ffff888020fe5000
> [ 43.803943] R13: ffff88801f8f2780 R14: ffff888020fe5170 R15: 0000000000000000
> [ 43.804324] FS: 00007f8f5ae81600(0000) GS:ffff8880e3684000(0000) knlGS:0000000000000000
> [ 43.804749] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 43.805069] CR2: 00007f8f5ac57910 CR3: 0000000021690001 CR4: 0000000000770ef0
> [ 43.805442] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> [ 43.805796] DR3: 0000000000000000 DR6: 00000000ffff07f0 DR7: 0000000000000400
> [ 43.806173] PKRU: 55555554
> [ 43.806345] Call Trace:
> [ 43.806558] <TASK>
> [ 43.806700] ? show_regs+0x6d/0x80
> [ 43.807345] ? die_addr+0x45/0xb0
> [ 43.807768] ? exc_general_protection+0x1ad/0x340
> [ 43.808360] ? asm_exc_general_protection+0x2b/0x30
> [ 43.808939] ? vma_merge_new_range+0x16a/0x930
> [ 43.809499] ? __do_sys_mremap+0x139f/0x15d0
> [ 43.810012] ? __do_sys_mremap+0x13a9/0x15d0
> [ 43.810528] ? __do_sys_mremap+0x139f/0x15d0
> [ 43.811043] ? __pfx___do_sys_mremap+0x10/0x10
> [ 43.811587] ? __this_cpu_preempt_check+0x21/0x30
> [ 43.812177] __x64_sys_mremap+0xc7/0x150
> [ 43.812652] ? syscall_trace_enter+0x14d/0x280
> [ 43.813201] x64_sys_call+0x1933/0x2150
> [ 43.813658] do_syscall_64+0x6d/0x150
> [ 43.814101] entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [ 43.814686] RIP: 0033:0x7f8f5ac3ee5d
> [ 43.815125] Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d8
> [ 43.817168] RSP: 002b:00007fff14f19058 EFLAGS: 00000217 ORIG_RAX: 0000000000000019
> [ 43.818037] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f8f5ac3ee5d
> [ 43.818430] RDX: 0000000000004000 RSI: 0000000000002000 RDI: 0000000020ffd000
> [ 43.818793] RBP: 00007fff14f19070 R08: 0000000020ffc000 R09: 0000000000000800
> [ 43.819160] R10: 0000000000000000 R11: 0000000000000217 R12: 00007fff14f19188
> [ 43.819540] R13: 0000000000401126 R14: 0000000000403e08 R15: 00007f8f5aeca000
> [ 43.819945] </TASK>
> [ 43.820066] Modules linked in:
> [ 43.820308] ---[ end trace 0000000000000000 ]---
> [ 43.820587] RIP: 0010:__do_sys_mremap+0x13a9/0x15d0
> [ 43.820874] Code: e8 ac 57 a8 ff 48 8b 85 30 fe ff ff 48 89 83 70 ff ff ff 49 89 c5 e9 2b f2 ff ff e8 91 57 a8 ff 485
> [ 43.821855] RSP: 0018:ffff88801aa67ce8 EFLAGS: 00010293
> [ 43.822150] RAX: dffffc0000000004 RBX: ffff88801aa67eb0 RCX: ffffffff81e42e5a
> [ 43.822543] RDX: ffff888011e6ca80 RSI: ffffffff81df64cf RDI: 0000000000000007
> [ 43.822928] RBP: ffff88801aa67ed8 R08: 0000000000000000 R09: ffffed10023cd950
> [ 43.823347] R10: 0000000010000000 R11: ffff888011e6d8d8 R12: ffff888020fe5000
> [ 43.823757] R13: ffff88801f8f2780 R14: ffff888020fe5170 R15: 0000000000000000
> [ 43.824156] FS: 00007f8f5ae81600(0000) GS:ffff8880e3684000(0000) knlGS:0000000000000000
> [ 43.824627] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 43.824959] CR2: 00007f8f5ac57910 CR3: 0000000021690001 CR4: 0000000000770ef0
> [ 43.825350] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> [ 43.825757] DR3: 0000000000000000 DR6: 00000000ffff07f0 DR7: 0000000000000400
> [ 43.826154] PKRU: 55555554
> "
>
> Hope this cound be insightful to you.
>
> Regards,
> Yi Lai
>
> ---
>
> If you don't need the following environment to reproduce the problem or if you
> already have one reproduced environment, please ignore the following information.
>
> How to reproduce:
> git clone https://gitlab.com/xupengfe/repro_vm_env.git
> cd repro_vm_env
> tar -xvf repro_vm_env.tar.gz
> cd repro_vm_env; ./start3.sh // it needs qemu-system-x86_64 and I used v7.1.0
> // start3.sh will load bzImage_2241ab53cbb5cdb08a6b2d4688feb13971058f65 v6.2-rc5 kernel
> // You could change the bzImage_xxx as you want
> // Maybe you need to remove line "-drive if=pflash,format=raw,readonly=on,file=./OVMF_CODE.fd \" for different qemu version
> You could use below command to log in, there is no password for root.
> ssh -p 10023 root@localhost
>
> After login vm(virtual machine) successfully, you could transfer reproduced
> binary to the vm by below way, and reproduce the problem in vm:
> gcc -pthread -o repro repro.c
> scp -P 10023 repro root@localhost:/root/
>
> Get the bzImage for target kernel:
> Please use target kconfig and copy it to kernel_src/.config
> make olddefconfig
> make -jx bzImage //x should equal or less than cpu num your pc has
>
> Fill the bzImage file into above start3.sh to load the target kernel in vm.
>
>
> Tips:
> If you already have qemu-system-x86_64, please ignore below info.
> If you want to install qemu v7.1.0 version:
> git clone https://github.com/qemu/qemu.git
> cd qemu
> git checkout -f v7.1.0
> mkdir build
> cd build
> yum install -y ninja-build.x86_64
> yum -y install libslirp-devel.x86_64
> ../configure --target-list=x86_64-softmmu --enable-kvm --enable-vnc --enable-gtk --enable-sdl --enable-usb-redir --enable-slirp
> make
> make install
>
>