[syzbot] [mm?] WARNING in folio_add_new_anon_rmap

0 views
Skip to first unread message

syzbot

unread,
Mar 15, 2026, 3:09:28 PM (11 hours ago) Mar 15
to Liam.H...@oracle.com, ak...@linux-foundation.org, da...@kernel.org, harr...@oracle.com, ja...@google.com, linux-...@vger.kernel.org, linu...@kvack.org, l...@kernel.org, ri...@surriel.com, syzkall...@googlegroups.com, vba...@kernel.org
Hello,

syzbot found the following issue on:

HEAD commit: f90aadf1c67c Add linux-next specific files for 20260311
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=12309806580000
kernel config: https://syzkaller.appspot.com/x/.config?x=2b10825359140979
dashboard link: https://syzkaller.appspot.com/bug?extid=e24a2e34fad0efbac047
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=10cb575a580000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=14db4d52580000

Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/aca9c54a7de2/disk-f90aadf1.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/736fd5e68863/vmlinux-f90aadf1.xz
kernel image: https://storage.googleapis.com/syzbot-assets/eb13b7d81d1b/bzImage-f90aadf1.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+e24a2e...@syzkaller.appspotmail.com

------------[ cut here ]------------
address < vma->vm_start || address + (nr << 12) > vma->vm_end
WARNING: mm/rmap.c:1682 at folio_add_new_anon_rmap+0x5fe/0x14b0 mm/rmap.c:1681, CPU#1: syz.2.19/6118
Modules linked in:
CPU: 1 UID: 0 PID: 6118 Comm: syz.2.19 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/27/2026
RIP: 0010:folio_add_new_anon_rmap+0x5fe/0x14b0 mm/rmap.c:1681
Code: 89 f5 4d 8b 36 4c 89 e7 4c 89 f6 e8 ec aa a9 ff 4d 39 f4 73 1a e8 82 a8 a9 ff 4c 8b 74 24 10 49 bc 00 00 00 00 00 fc ff df 90 <0f> 0b 90 eb 5a 44 89 f8 c1 e0 0c 48 98 49 01 c4 49 83 c5 08 4c 89
RSP: 0018:ffffc900036675a0 EFLAGS: 00010293
RAX: ffffffff821d041e RBX: ffffea0001c0c1c0 RCX: ffff888060bf5b80
RDX: 0000000000000000 RSI: 00002000004ca000 RDI: 00002000004cb000
RBP: 0000000000000000 R08: ffffea0001c0c1c7 R09: 1ffffd4000381838
R10: dffffc0000000000 R11: fffff94000381839 R12: dffffc0000000000
R13: ffff8880784ad788 R14: ffffea0001c0c1c8 R15: 0000000000000001
FS: 00007f9a968ce6c0(0000) GS:ffff88812553e000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00002000002b8000 CR3: 000000007c646000 CR4: 00000000003526f0
Call Trace:
<TASK>
mfill_atomic_install_pte+0x578/0x870 mm/userfaultfd.c:390
__mfill_atomic_pte+0x3c4/0x5f0 mm/userfaultfd.c:523
mfill_atomic_pte_copy mm/userfaultfd.c:557 [inline]
mfill_atomic_pte mm/userfaultfd.c:865 [inline]
mfill_atomic mm/userfaultfd.c:923 [inline]
mfill_atomic_copy+0x4d9/0x1330 mm/userfaultfd.c:950
userfaultfd_copy fs/userfaultfd.c:1642 [inline]
userfaultfd_ioctl+0x2b8a/0x4b00 fs/userfaultfd.c:2059
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f9a9599c799
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f9a968ce028 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007f9a95c15fa0 RCX: 00007f9a9599c799
RDX: 0000200000000040 RSI: 00000000c028aa03 RDI: 0000000000000003
RBP: 00007f9a95a32c99 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f9a95c16038 R14: 00007f9a95c15fa0 R15: 00007ffd373c5448
</TASK>


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzk...@googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup

syzbot

unread,
Mar 15, 2026, 10:02:20 PM (4 hours ago) Mar 15
to linux-...@vger.kernel.org, syzkall...@googlegroups.com
For archival purposes, forwarding an incoming command email to
linux-...@vger.kernel.org, syzkall...@googlegroups.com.

***

Subject: [PATCH] mm/userfaultfd: re-validate vma in mfill_atomic() loop under CONFIG_PER_VMA_LOCK
Author: karti...@gmail.com

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master


Under CONFIG_PER_VMA_LOCK, mfill_atomic() holds only a per-VMA read
lock (vma_start_read) across its page-by-page copy loop. Unlike
mmap_read_lock, this does not prevent a concurrent mmap_write_lock()
from splitting the vma mid-loop via UFFDIO_UNREGISTER.

When the vma is split, vm_end of state.vma is shrunk in place. On the
next iteration, mfill_atomic_install_pte() calls folio_add_new_anon_rmap()
with state.dst_addr >= vma->vm_end, triggering the sanity check:

address < vma->vm_start || address + (nr << 12) > vma->vm_end
WARNING: mm/rmap.c:1682 folio_add_new_anon_rmap+0x5fe/0x14b0

Fix this by checking on each loop iteration whether state.dst_addr
has fallen outside state.vma. If so, release the stale vma, update
dst_start and len to reflect the current position, and re-lookup the
vma via mfill_get_vma().

Reported-by: syzbot+e24a2e...@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=e24a2e34fad0efbac047
Signed-off-by: Deepanshu Kartikey <Karti...@gmail.com>
---
mm/userfaultfd.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index 9ffc80d0a51b..519be02fad38 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -910,8 +910,17 @@ static __always_inline ssize_t mfill_atomic(struct userfaultfd_ctx *ctx,

while (state.src_addr < src_start + len) {
VM_WARN_ON_ONCE(state.dst_addr >= dst_start + len);
+ if (state.dst_addr < state.vma->vm_start ||
+ state.dst_addr >= state.vma->vm_end) {
+ mfill_put_vma(&state);
+ state.dst_start = state.dst_addr;
+ state.len = dst_start + len - state.dst_addr;
+ err = mfill_get_vma(&state);
+ if (err)
+ break;
+ }

- err = mfill_get_pmd(&state);
+ err = mfill_get_pmd(&state);
if (err)
break;

--
2.43.0

syzbot

unread,
Mar 15, 2026, 10:40:06 PM (3 hours ago) Mar 15
to karti...@gmail.com, linux-...@vger.kernel.org, syzkall...@googlegroups.com
Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+e24a2e...@syzkaller.appspotmail.com
Tested-by: syzbot+e24a2e...@syzkaller.appspotmail.com

Tested on:

commit: b84a0ebe Add linux-next specific files for 20260313
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=13303406580000
kernel config: https://syzkaller.appspot.com/x/.config?x=d079c776411aaf59
dashboard link: https://syzkaller.appspot.com/bug?extid=e24a2e34fad0efbac047
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
patch: https://syzkaller.appspot.com/x/patch.diff?x=150ba2d6580000

Note: testing is done by a robot and is best-effort only.

syzbot

unread,
1:11 AM (1 hour ago) 1:11 AM
to linux-...@vger.kernel.org, syzkall...@googlegroups.com
For archival purposes, forwarding an incoming command email to
linux-...@vger.kernel.org, syzkall...@googlegroups.com.

***

Subject: [PATCH] mm/userfaultfd: validate dst_addr after re-acquiring VMA lock in mfill_copy_folio_retry
mfill_copy_folio_retry() drops the VMA lock to perform
copy_from_user() without holding it, then reacquires it
via mfill_get_vma(). However, mfill_get_vma() only validates
that dst_start is within the VMA bounds, not dst_addr (the
current page being processed).

A concurrent UFFDIO_UNREGISTER can split the VMA during the
window where the lock is dropped, shrinking vma->vm_end. When
mfill_get_vma() reacquires the lock, it finds the VMA using
dst_start which may still be valid, but dst_addr may now fall
outside the split VMA's bounds.

This causes folio_add_new_anon_rmap() to trigger its sanity
check:

address < vma->vm_start || address + (nr << 12) > vma->vm_end
WARNING: mm/rmap.c:1682 folio_add_new_anon_rmap+0x5fe/0x14b0

Fix this by validating dst_addr against the reacquired VMA
bounds after mfill_get_vma() returns in mfill_copy_folio_retry().
mm/userfaultfd.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index 9ffc80d0a51b..dbf16c9bcf6f 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -467,6 +467,16 @@ static int mfill_copy_folio_retry(struct mfill_state *state, struct folio *folio
if (err)
return err;

+ /*
+ * VMA may have been split while the lock was dropped for
+ * copy_from_user(). mfill_get_vma() only validates dst_start
+ * but not dst_addr (current page). Re-validate dst_addr against
+ * the reacquired VMA bounds before installing the PTE.
+ */
+ if (state->dst_addr < state->vma->vm_start ||
+ state->dst_addr >= state->vma->vm_end)
+ return -EFAULT;
+
err = mfill_get_pmd(state);
if (err)
return err;
--
2.43.0

Reply all
Reply to author
Forward
0 new messages