[syzbot] [mm?] general protection fault in zap_huge_pmd

4 views
Skip to first unread message

syzbot

unread,
Mar 18, 2026, 11:03:25 AM (yesterday) Mar 18
to Liam.H...@oracle.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, da...@kernel.org, dev....@arm.com, lance...@linux.dev, linux-...@vger.kernel.org, linu...@kvack.org, l...@kernel.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com, z...@nvidia.com
Hello,

syzbot found the following issue on:

HEAD commit: b84a0ebe421c Add linux-next specific files for 20260313
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=119ddd52580000
kernel config: https://syzkaller.appspot.com/x/.config?x=e7280ad1f68b2dce
dashboard link: https://syzkaller.appspot.com/bug?extid=de14f7701c22477db718
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=173b44da580000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=1537b8da580000

Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/09145161a8a9/disk-b84a0ebe.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/b64c254e474c/vmlinux-b84a0ebe.xz
kernel image: https://storage.googleapis.com/syzbot-assets/a7c33f5f7f45/bzImage-b84a0ebe.xz

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

Oops: general protection fault, probably for non-canonical address 0xdffffc0000000003: 0000 [#1] SMP KASAN PTI
KASAN: null-ptr-deref in range [0x0000000000000018-0x000000000000001f]
CPU: 1 UID: 0 PID: 5994 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2026
RIP: 0010:folio_test_anon include/linux/page-flags.h:718 [inline]
RIP: 0010:zap_huge_pmd+0x7b1/0x1030 mm/huge_memory.c:2463
Code: 08 00 00 e8 11 e0 92 ff 48 c7 44 24 10 00 00 00 00 4c 8b 3c 24 4c 8d 75 18 4c 89 f0 48 c1 e8 03 48 b9 00 00 00 00 00 fc ff df <80> 3c 08 00 74 08 4c 89 f7 e8 f1 43 fc ff 49 8b 1e 48 89 de 48 83
RSP: 0018:ffffc90003bb7550 EFLAGS: 00010206
RAX: 0000000000000003 RBX: f000000000000000 RCX: dffffc0000000000
RDX: 0000000000000000 RSI: 0000000000000006 RDI: 0000000000000003
RBP: 0000000000000000 R08: ffff88807cc9802f R09: 1ffff1100f993005
R10: dffffc0000000000 R11: ffffed100f993006 R12: ffff88807cc98028
R13: fffffffffffffa00 R14: 0000000000000018 R15: ffffc90003bb7ac0
FS: 0000000000000000(0000) GS:ffff888124ee0000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00002000000000c0 CR3: 000000000e94a000 CR4: 00000000003526f0
Call Trace:
<TASK>
zap_pmd_range mm/memory.c:1990 [inline]
zap_pud_range mm/memory.c:2032 [inline]
zap_p4d_range mm/memory.c:2053 [inline]
__zap_vma_range+0xa82/0x4bd0 mm/memory.c:2093
unmap_vmas+0x379/0x530 mm/memory.c:2162
exit_mmap+0x280/0xa10 mm/mmap.c:1302
__mmput+0x118/0x430 kernel/fork.c:1180
exit_mm+0x18e/0x250 kernel/exit.c:581
do_exit+0x8b9/0x2490 kernel/exit.c:962
do_group_exit+0x21b/0x2d0 kernel/exit.c:1116
__do_sys_exit_group kernel/exit.c:1127 [inline]
__se_sys_exit_group kernel/exit.c:1125 [inline]
__x64_sys_exit_group+0x3f/0x40 kernel/exit.c:1125
x64_sys_call+0x221a/0x2240 arch/x86/include/generated/asm/syscalls_64.h:232
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:0x7fdd0b39c799
Code: Unable to access opcode bytes at 0x7fdd0b39c76f.
RSP: 002b:00007fff630f1d78 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fdd0b39c799
RDX: 0000000000000064 RSI: 0000000000000000 RDI: 0000000000000000
RBP: 0000000000000003 R08: 0000000000000000 R09: 00007fdd0b5e63e0
R10: 0000000000000001 R11: 0000000000000246 R12: 0000000000000000
R13: 00007fdd0b5e63e0 R14: 0000000000000003 R15: 00007fff630f1e30
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:folio_test_anon include/linux/page-flags.h:718 [inline]
RIP: 0010:zap_huge_pmd+0x7b1/0x1030 mm/huge_memory.c:2463
Code: 08 00 00 e8 11 e0 92 ff 48 c7 44 24 10 00 00 00 00 4c 8b 3c 24 4c 8d 75 18 4c 89 f0 48 c1 e8 03 48 b9 00 00 00 00 00 fc ff df <80> 3c 08 00 74 08 4c 89 f7 e8 f1 43 fc ff 49 8b 1e 48 89 de 48 83
RSP: 0018:ffffc90003bb7550 EFLAGS: 00010206
RAX: 0000000000000003 RBX: f000000000000000 RCX: dffffc0000000000
RDX: 0000000000000000 RSI: 0000000000000006 RDI: 0000000000000003
RBP: 0000000000000000 R08: ffff88807cc9802f R09: 1ffff1100f993005
R10: dffffc0000000000 R11: ffffed100f993006 R12: ffff88807cc98028
R13: fffffffffffffa00 R14: 0000000000000018 R15: ffffc90003bb7ac0
FS: 0000000000000000(0000) GS:ffff888124ee0000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00002000000000c0 CR3: 000000000e94a000 CR4: 00000000003526f0
----------------
Code disassembly (best guess):
0: 08 00 or %al,(%rax)
2: 00 e8 add %ch,%al
4: 11 e0 adc %esp,%eax
6: 92 xchg %eax,%edx
7: ff 48 c7 decl -0x39(%rax)
a: 44 24 10 rex.R and $0x10,%al
d: 00 00 add %al,(%rax)
f: 00 00 add %al,(%rax)
11: 4c 8b 3c 24 mov (%rsp),%r15
15: 4c 8d 75 18 lea 0x18(%rbp),%r14
19: 4c 89 f0 mov %r14,%rax
1c: 48 c1 e8 03 shr $0x3,%rax
20: 48 b9 00 00 00 00 00 movabs $0xdffffc0000000000,%rcx
27: fc ff df
* 2a: 80 3c 08 00 cmpb $0x0,(%rax,%rcx,1) <-- trapping instruction
2e: 74 08 je 0x38
30: 4c 89 f7 mov %r14,%rdi
33: e8 f1 43 fc ff call 0xfffc4429
38: 49 8b 1e mov (%r14),%rbx
3b: 48 89 de mov %rbx,%rsi
3e: 48 rex.W
3f: 83 .byte 0x83


---
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

Lance Yang

unread,
Mar 18, 2026, 12:53:56 PM (yesterday) Mar 18
to syzbot, da...@kernel.org, l...@kernel.org, ryan.r...@arm.com, npa...@redhat.com, Liam.H...@oracle.com, z...@nvidia.com, linu...@kvack.org, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, linux-...@vger.kernel.org, syzkall...@googlegroups.com, dev....@arm.com


On 2026/3/18 23:03, syzbot wrote:
> Hello,
>
> syzbot found the following issue on:
>
> HEAD commit: b84a0ebe421c Add linux-next specific files for 20260313
> git tree: linux-next
> console output: https://syzkaller.appspot.com/x/log.txt?x=119ddd52580000
> kernel config: https://syzkaller.appspot.com/x/.config?x=e7280ad1f68b2dce
> dashboard link: https://syzkaller.appspot.com/bug?extid=de14f7701c22477db718
> 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=173b44da580000
> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=1537b8da580000
>
> Downloadable assets:
> disk image: https://storage.googleapis.com/syzbot-assets/09145161a8a9/disk-b84a0ebe.raw.xz
> vmlinux: https://storage.googleapis.com/syzbot-assets/b64c254e474c/vmlinux-b84a0ebe.xz
> kernel image: https://storage.googleapis.com/syzbot-assets/a7c33f5f7f45/bzImage-b84a0ebe.xz
>
> IMPORTANT: if you fix the issue, please add the following tag to the commit:
> Reported-by: syzbot+de14f7...@syzkaller.appspotmail.com
>
> Oops: general protection fault, probably for non-canonical address 0xdffffc0000000003: 0000 [#1] SMP KASAN PTI

Looks like it hits a general protection fault in zap_huge_pmd() while
dereferencing folio->mapping via folio_test_anon() ...

zap_huge_pmd() fails to handle non-present, non-none PMD entries that
are not valid PMD softleaf entries, leaving folio as NULL and
dereferencing it ...

For PMD-sized hugetlb mappings like the reproducer above,
hugetlb/userfaultfd would make such PMD entries that can be
non-present and non-none without being valid PMD softleaf entries?

I'll look into it :)

Thanks,
Lance

Lorenzo Stoakes (Oracle)

unread,
Mar 18, 2026, 1:26:41 PM (yesterday) Mar 18
to syzbot, Liam.H...@oracle.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, da...@kernel.org, dev....@arm.com, lance...@linux.dev, linux-...@vger.kernel.org, linu...@kvack.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com, z...@nvidia.com, Mike Rapoport, Harry Yoo
+cc Mike for uffd, Harry for fix that also resolves this, see below

On Wed, Mar 18, 2026 at 08:03:22AM -0700, syzbot wrote:
> Hello,
>
> syzbot found the following issue on:
>
> HEAD commit: b84a0ebe421c Add linux-next specific files for 20260313

For some reason I have to git pull --tags to get this... commit hash locally?
Strange.

> git tree: linux-next
> console output: https://syzkaller.appspot.com/x/log.txt?x=119ddd52580000
> kernel config: https://syzkaller.appspot.com/x/.config?x=e7280ad1f68b2dce
> dashboard link: https://syzkaller.appspot.com/bug?extid=de14f7701c22477db718
> 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=173b44da580000
> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=1537b8da580000

@SYZKALLER guys:

Note: the repro is incorrectly labelling;

// ioctl$UFFDIO_CONTINUE arguments: [
// fd: fd_uffd (resource)
// cmd: const = 0xc020aa08 (4 bytes)

as UFFDIO_CONTINUE (0x7), it's actually UFFDIO_POISION (0x8) as you can see
from least-significant byte.

It's also stating things like mmap flags wrong e.g.:

/*flags=MAP_UNINITIALIZED|MAP_POPULATE|MAP_NORESERVE|MAP_NONBLOCK|MAP_HUGETLB|0x8c4b815a506002b2*/
0x8c4b815a5465c2b2ul,

AT LEAST MAKE THE NUMBERS MATCH :) this doesn't help with debugging.

AI hallucinations?

It also never returns with an error if a syscall doesn't work which means the
repro can run 'ok' but actually be failing on something, this really slows down repro'ing.

Maybe hard, but be good to figure out maintainers based on the stuff the repro
uses uffd -> uffd entry in MAINTAINERS :)

OK rants done :) got it repro'ing locally now.

>
> Downloadable assets:
> disk image: https://storage.googleapis.com/syzbot-assets/09145161a8a9/disk-b84a0ebe.raw.xz
> vmlinux: https://storage.googleapis.com/syzbot-assets/b64c254e474c/vmlinux-b84a0ebe.xz
> kernel image: https://storage.googleapis.com/syzbot-assets/a7c33f5f7f45/bzImage-b84a0ebe.xz
>
> IMPORTANT: if you fix the issue, please add the following tag to the commit:
> Reported-by: syzbot+de14f7...@syzkaller.appspotmail.com
>
> Oops: general protection fault, probably for non-canonical address 0xdffffc0000000003: 0000 [#1] SMP KASAN PTI
> KASAN: null-ptr-deref in range [0x0000000000000018-0x000000000000001f]
> CPU: 1 UID: 0 PID: 5994 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full)
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2026
> RIP: 0010:folio_test_anon include/linux/page-flags.h:718 [inline]

static __always_inline bool folio_test_anon(const struct folio *folio)
{
return ((unsigned long)folio->mapping & FOLIO_MAPPING_ANON) != 0; <-- NULL folio
}


> RIP: 0010:zap_huge_pmd+0x7b1/0x1030 mm/huge_memory.c:2463

int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
pmd_t *pmd, unsigned long addr)
{
...

if (!vma_is_dax(vma) && vma_is_special_huge(vma)) {
...
} else if (is_huge_zero_pmd(orig_pmd)) {
...
} else {
struct folio *folio = NULL;

...

if (pmd_present(orig_pmd)) {
...
} else if (pmd_is_valid_softleaf(orig_pmd)) {
...
}

if (folio_test_anon(folio)) { <-- if !pmd_present() && !pmd_is_valid_softleaf(orig_pmd)

Yikes. We should probably put an } else { VM_WARN_ON_ONCE(1); } at least above
this...




> Code: 08 00 00 e8 11 e0 92 ff 48 c7 44 24 10 00 00 00 00 4c 8b 3c 24 4c 8d 75 18 4c 89 f0 48 c1 e8 03 48 b9 00 00 00 00 00 fc ff df <80> 3c 08 00 74 08 4c 89 f7 e8 f1 43 fc ff 49 8b 1e 48 89 de 48 83
> RSP: 0018:ffffc90003bb7550 EFLAGS: 00010206
> RAX: 0000000000000003 RBX: f000000000000000 RCX: dffffc0000000000
> RDX: 0000000000000000 RSI: 0000000000000006 RDI: 0000000000000003
> RBP: 0000000000000000 R08: ffff88807cc9802f R09: 1ffff1100f993005
> R10: dffffc0000000000 R11: ffffed100f993006 R12: ffff88807cc98028
> R13: fffffffffffffa00 R14: 0000000000000018 R15: ffffc90003bb7ac0
> FS: 0000000000000000(0000) GS:ffff888124ee0000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00002000000000c0 CR3: 000000000e94a000 CR4: 00000000003526f0
> Call Trace:
> <TASK>
> zap_pmd_range mm/memory.c:1990 [inline]

else if (zap_huge_pmd(tlb, vma, pmd, addr)) { <-- here

> zap_pud_range mm/memory.c:2032 [inline]
> zap_p4d_range mm/memory.c:2053 [inline]
> __zap_vma_range+0xa82/0x4bd0 mm/memory.c:2093
> unmap_vmas+0x379/0x530 mm/memory.c:2162
> exit_mmap+0x280/0xa10 mm/mmap.c:1302
> __mmput+0x118/0x430 kernel/fork.c:1180
> exit_mm+0x18e/0x250 kernel/exit.c:581
> do_exit+0x8b9/0x2490 kernel/exit.c:962
> do_group_exit+0x21b/0x2d0 kernel/exit.c:1116
> __do_sys_exit_group kernel/exit.c:1127 [inline]
> __se_sys_exit_group kernel/exit.c:1125 [inline]
> __x64_sys_exit_group+0x3f/0x40 kernel/exit.c:1125
> x64_sys_call+0x221a/0x2240 arch/x86/include/generated/asm/syscalls_64.h:232
> 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

So this is on process teardown.

Looking at the repro (+ trying to decode what it ACTUALLY does :) it looks like
it's installing a PTE_MARKER_POISONED at a PMD level via hugetlb, because since
commit 8a13897fb0da ("mm: userfaultfd: support UFFDIO_POISON for hugetlbfs")
this is supported.

Normally this would be handled by __unmap_hugepage_range():

if (unlikely(is_vm_hugetlb_page(vma))) {
...
__unmap_hugepage_range(tlb, vma, start, end, NULL, zap_flags);
} else {
...
next = zap_p4d_range(tlb, vma, pgd, addr, next, details);
}

But for some reason the zap_p4d_range() path is being used.

I got a the repro reliably working locally (not sure why syzkaller didn't
bisect) so I have bisected it to commit 7d4d4de3ac3e ("userfaultfd: introduce
mfill_get_vma() and mfill_put_vma()").

And.. of course, after spending (wasting? :) a long time on this, it's already
fixed...

It seems it's fixed by https://lore.kernel.org/linux-mm/abehBY7QakYF9bK4@hyeyoo/

Before mfill_atomic() would initialise some mfill_state helper struct like this:

struct mfill_state state = (struct mfill_state){
.ctx = ctx,
.dst_start = dst_start,
.src_start = src_start,
.flags = flags,

.src_addr = src_start,
.dst_addr = dst_start,
};

BUT not initialise .len = len

So length from then on is assumed to be 0.

OK so the repro, again, generates TOTALLY incorrect labelling:

// ioctl$UFFDIO_CONTINUE arguments: [
// fd: fd_uffd (resource)
// cmd: const = 0xc020aa08 (4 bytes)
// arg: ptr[in, uffdio_continue] {
// uffdio_continue {
// range: uffdio_range {
// start: VMA[0xc00000]
// len: len = 0xc00000 (8 bytes)
// }
// mode: uffdio_continue_mode = 0x0 (8 bytes)
// mapped: int64 = 0x0 (8 bytes)
// }
// }
// ]
*(uint64_t*)0x200000000280 = 0x200000400000;
*(uint64_t*)0x200000000288 = 0xc00000;
*(uint64_t*)0x200000000290 = 0;
syscall(__NR_ioctl, /*fd=*/r[0], /*cmd=*/0xc020aa08,
/*arg=*/0x200000000280ul);

In reality this is:

struct uffdio_poison poison = {
.range = {
.start = 0x200000400000,
.len = 0xc00000, /* 12MB */
},
.mode = 0,
};

(!!!)

Which in the kernel calls

userfaultfd_ioctl()
-> userfaultfd_poison()
-> validate_range() -> validate_unaligned_range() <-- would ordinarily reject 0 len!!
-> mfill_atomic_poison()
-> mfill_atomic() [ hits bug]
-> mfill_get_vma()
-> uffd_mfill_lock(..., len=0!)

static struct vm_area_struct *uffd_mfill_lock(struct mm_struct *dst_mm,
unsigned long dst_start,
unsigned long len)
{
struct vm_area_struct *dst_vma;

dst_vma = uffd_lock_vma(dst_mm, dst_start);
if (IS_ERR(dst_vma) || validate_dst_vma(dst_vma, dst_start + len))
return dst_vma;
}

Here validate_dst_vma() succeeds trivially as len is 0

BUT. The rest of mfill_atomic() uses len, not state.len.

So this results in ONLY the validation check using the bogus len=0, and works
with a 12MB size.

Note that in the repro, we try to map a hugetlb VMA of (weirdly) 9.36 MB.

Because we align the hugetlb and round it up from this to 10mb we get VMAs like:

0x1ffffffff000 0x200000a00000 0x200001001000
|---------|------------------------------|-----------------------|---------|
|1pg none | 2560 pages (10 MB) hugetlb | 1535 pages (6MB) WRX | 1pg none|
|---------|------------------------------|-----------------------|---------|
0x200000000000 0x200001000000

Because of the len bug, we happily try to install poison markers into 2 MB of
the 1535 page anon WRX region which is not hugetlb and then BOOM.

So Harry's fix resolves this, but we should handle this case better in
zap_huge_pmd(), I will send a patch for that.

Cheers, Lorenzo

Lorenzo Stoakes (Oracle)

unread,
Mar 18, 2026, 1:35:34 PM (yesterday) Mar 18
to Lance Yang, syzbot, da...@kernel.org, ryan.r...@arm.com, npa...@redhat.com, Liam.H...@oracle.com, z...@nvidia.com, linu...@kvack.org, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, linux-...@vger.kernel.org, syzkall...@googlegroups.com, dev....@arm.com
On Thu, Mar 19, 2026 at 12:53:46AM +0800, Lance Yang wrote:
> Looks like it hits a general protection fault in zap_huge_pmd() while
> dereferencing folio->mapping via folio_test_anon() ...
>
> zap_huge_pmd() fails to handle non-present, non-none PMD entries that
> are not valid PMD softleaf entries, leaving folio as NULL and
> dereferencing it ...
>
> For PMD-sized hugetlb mappings like the reproducer above,
> hugetlb/userfaultfd would make such PMD entries that can be
> non-present and non-none without being valid PMD softleaf entries?

Yeah, exactly :) interesting how it gets there though.

Even after I figured out this was fixed wanted to track it down!

See
https://lore.kernel.org/linux-mm/6b3d7ad7-49e1-407a...@lucifer.local/

>
> I'll look into it :)

As per above, I already did the analysis on this monster, it's fixed already (of
course!).

I am going to send a patch to make this bit of the code more robust anyway!

Cheers, Lorenzo

Aleksandr Nogikh

unread,
Mar 18, 2026, 5:54:31 PM (23 hours ago) Mar 18
to Lorenzo Stoakes (Oracle), syzbot, Liam.H...@oracle.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, da...@kernel.org, dev....@arm.com, lance...@linux.dev, linux-...@vger.kernel.org, linu...@kvack.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com, z...@nvidia.com, Mike Rapoport, Harry Yoo, syzkaller
On Wed, Mar 18, 2026 at 6:26 PM 'Lorenzo Stoakes (Oracle)' via
syzkaller-bugs <syzkall...@googlegroups.com> wrote:
>
> +cc Mike for uffd, Harry for fix that also resolves this, see below
>
> On Wed, Mar 18, 2026 at 08:03:22AM -0700, syzbot wrote:
> > Hello,
> >
> > syzbot found the following issue on:
> >
> > HEAD commit: b84a0ebe421c Add linux-next specific files for 20260313
>
> For some reason I have to git pull --tags to get this... commit hash locally?
> Strange.
>
> > git tree: linux-next
> > console output: https://syzkaller.appspot.com/x/log.txt?x=119ddd52580000
> > kernel config: https://syzkaller.appspot.com/x/.config?x=e7280ad1f68b2dce
> > dashboard link: https://syzkaller.appspot.com/bug?extid=de14f7701c22477db718
> > 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=173b44da580000
> > C reproducer: https://syzkaller.appspot.com/x/repro.c?x=1537b8da580000
>
> @SYZKALLER guys:
>
> Note: the repro is incorrectly labelling;
>
> // ioctl$UFFDIO_CONTINUE arguments: [
> // fd: fd_uffd (resource)
> // cmd: const = 0xc020aa08 (4 bytes)
>
> as UFFDIO_CONTINUE (0x7), it's actually UFFDIO_POISION (0x8) as you can see
> from least-significant byte.

Hmmm, that shouldn't have happened. Syzkaller normally tries to avoid
mutating one ioctl into another.
I've filed https://github.com/google/syzkaller/issues/6950.

>
> It's also stating things like mmap flags wrong e.g.:
>
> /*flags=MAP_UNINITIALIZED|MAP_POPULATE|MAP_NORESERVE|MAP_NONBLOCK|MAP_HUGETLB|0x8c4b815a506002b2*/
> 0x8c4b815a5465c2b2ul,
>
> AT LEAST MAKE THE NUMBERS MATCH :) this doesn't help with debugging.

MAP_UNINITIALIZED = 0x4000000
MAP_POPULATE = 0x8000
MAP_NORESERVE = 0x4000
MAP_NONBLOCK = 0x10000
MAP_HUGETLB = 0x40000
rest = 0x8c4b815a506002b2
print(hex(MAP_UNINITIALIZED + MAP_POPULATE + MAP_NORESERVE +
MAP_HUGETLB + rest))

gives me exactly 0x8c4b815a5465c2b2ul. What was the problem here? :)

>
> AI hallucinations?
>
> It also never returns with an error if a syscall doesn't work which means the
> repro can run 'ok' but actually be failing on something, this really slows down repro'ing.

That's an interesting point. There will be corner cases where a
syscall is expected to fail or may start failing after N iterations
and that's fine, but the idea is totally worth exploring further.

>
> Maybe hard, but be good to figure out maintainers based on the stuff the repro
> uses uffd -> uffd entry in MAINTAINERS :)

It's easily doable, but there's a problem: uffd maintainers will be
CC'd whenever uffd is used in a reproducer, which may not always mean
that it truly caused the crash. We do minimize reproducers, but there
always remain some weird cases where unrelated syscalls persist e.g.
only to force some specific timings or to get specific file handle
numbers.

That's why we mostly rely on stack traces to identify subsystems.

--
Aleksandr
> --
> You received this message because you are subscribed to the Google Groups "syzkaller-bugs" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to syzkaller-bug...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/syzkaller-bugs/6b3d7ad7-49e1-407a-903d-3103704160d8%40lucifer.local.

Lance Yang

unread,
Mar 18, 2026, 10:59:17 PM (18 hours ago) Mar 18
to Lorenzo Stoakes (Oracle), syzbot, da...@kernel.org, ryan.r...@arm.com, npa...@redhat.com, Liam.H...@oracle.com, z...@nvidia.com, linu...@kvack.org, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, linux-...@vger.kernel.org, syzkall...@googlegroups.com, dev....@arm.com
Cool, thanks!

Lance Yang

unread,
Mar 18, 2026, 11:09:24 PM (18 hours ago) Mar 18
to l...@kernel.org, syzbot+de14f7...@syzkaller.appspotmail.com, Liam.H...@oracle.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, da...@kernel.org, dev....@arm.com, lance...@linux.dev, linux-...@vger.kernel.org, linu...@kvack.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com, z...@nvidia.com, rp...@kernel.org, harr...@oracle.com

On Wed, Mar 18, 2026 at 05:26:32PM +0000, Lorenzo Stoakes (Oracle) wrote:
>+cc Mike for uffd, Harry for fix that also resolves this, see below
>
>On Wed, Mar 18, 2026 at 08:03:22AM -0700, syzbot wrote:
>> Hello,
>>
>> syzbot found the following issue on:
>>
>> HEAD commit: b84a0ebe421c Add linux-next specific files for 20260313
>
>For some reason I have to git pull --tags to get this... commit hash locally?
>Strange.
>
>> git tree: linux-next
>> console output: https://syzkaller.appspot.com/x/log.txt?x=119ddd52580000
>> kernel config: https://syzkaller.appspot.com/x/.config?x=e7280ad1f68b2dce
>> dashboard link: https://syzkaller.appspot.com/bug?extid=de14f7701c22477db718
>> 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=173b44da580000
>> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=1537b8da580000
>
>@SYZKALLER guys:
>
>Note: the repro is incorrectly labelling;
>
> // ioctl$UFFDIO_CONTINUE arguments: [
> // fd: fd_uffd (resource)
> // cmd: const = 0xc020aa08 (4 bytes)
>
>as UFFDIO_CONTINUE (0x7), it's actually UFFDIO_POISION (0x8) as you can see
>from least-significant byte.

#define _UFFDIO_CONTINUE (0x07)
#define _UFFDIO_POISON (0x08)

Ouch. I spent quite some time trying to figure out how UFFDIO_CONTINUE
could possibly install PTE markers and push the loop past the VMA
boundary - turns out it can't, because it was UFFDIO_POISON all along.
Thanks for the thorough analysis Lorenzo!

Mike Rapoport

unread,
1:46 AM (16 hours ago) 1:46 AM
to Lorenzo Stoakes (Oracle), syzbot, Liam.H...@oracle.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, da...@kernel.org, dev....@arm.com, lance...@linux.dev, linux-...@vger.kernel.org, linu...@kvack.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com, z...@nvidia.com, Harry Yoo
On Wed, Mar 18, 2026 at 05:26:32PM +0000, Lorenzo Stoakes (Oracle) wrote:
As Andrey Vagin pointed off-list, you can run strace repro and see the
syscall arguments quite nicely :-)

> So Harry's fix resolves this,

and that's the important bit ;-P

> but we should handle this case better in zap_huge_pmd(), I will send a
> patch for that.

> Cheers, Lorenzo

--
Sincerely yours,
Mike.

Lorenzo Stoakes (Oracle)

unread,
4:54 AM (12 hours ago) 4:54 AM
to Mike Rapoport, syzbot, Liam.H...@oracle.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, da...@kernel.org, dev....@arm.com, lance...@linux.dev, linux-...@vger.kernel.org, linu...@kvack.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com, z...@nvidia.com, Harry Yoo
Yeah, but we really shouldn't need to have to :)

>
> > So Harry's fix resolves this,
>
> and that's the important bit ;-P

Yep

>
> > but we should handle this case better in zap_huge_pmd(), I will send a
> > patch for that.

And already did this ^ :)

>
> > Cheers, Lorenzo
>
> --
> Sincerely yours,
> Mike.

Cheers, Lorenzo

Lorenzo Stoakes (Oracle)

unread,
6:05 AM (11 hours ago) 6:05 AM
to Aleksandr Nogikh, syzbot, Liam.H...@oracle.com, ak...@linux-foundation.org, bao...@kernel.org, baoli...@linux.alibaba.com, da...@kernel.org, dev....@arm.com, lance...@linux.dev, linux-...@vger.kernel.org, linu...@kvack.org, npa...@redhat.com, ryan.r...@arm.com, syzkall...@googlegroups.com, z...@nvidia.com, Mike Rapoport, Harry Yoo, syzkaller
ugh, yeah sorry I misread that:

/*flags=MAP_UNINITIALIZED|MAP_POPULATE|MAP_NORESERVE|MAP_NONBLOCK|MAP_HUGETLB|0x8c4b815a506002b2*/
^^^^^^^^^^^^^^^^^^

I read it that 0x8c4... value being the value that the preceding flags come
to but obviously |x|y|z|...|<some hex val> means it's additional garbage right?

But it's not really decoding properly here at all:

Writing a bit of code to decode, 0x8c4b815a5465c2b2 becomes:

MAP_HUGE_2MB|MAP_HUGETLB|MAP_NONBLOCK|MAP_POPULATE|MAP_NORESERVE|MAP_ANONYMOUS|MAP_FIXED|MAP_PRIVATE|unknown=0x8c4b815a00600280

So I do think that your algorithm could do with some tweaking here :)
especially MAP_FIXED, as it wasn't clear as to whether the addr passed was
a hint or not.

(MAP_UNINITIALIZED overlapping with hugetlb sizing flags is annoying, as is
how that's encoded too.)

(I put the code at https://github.com/ljskernel/mm/tree/main/tools - it may
or may not be buggy :))

>
> >
> > AI hallucinations?
> >
> > It also never returns with an error if a syscall doesn't work which means the
> > repro can run 'ok' but actually be failing on something, this really slows down repro'ing.
>
> That's an interesting point. There will be corner cases where a
> syscall is expected to fail or may start failing after N iterations
> and that's fine, but the idea is totally worth exploring further.

Yeah for sure, but at least outputting the information would be useful, so
you could have the same exact behaviour just with more stderr output?

>
> >
> > Maybe hard, but be good to figure out maintainers based on the stuff the repro
> > uses uffd -> uffd entry in MAINTAINERS :)
>
> It's easily doable, but there's a problem: uffd maintainers will be
> CC'd whenever uffd is used in a reproducer, which may not always mean
> that it truly caused the crash. We do minimize reproducers, but there
> always remain some weird cases where unrelated syscalls persist e.g.
> only to force some specific timings or to get specific file handle
> numbers.

I don't want to speak for Mike but will anyway ;) [speak up Mike if you
disagree :P] - I think it'd be fine to do that and just let it cc- some
people inappropriately sometimes.

Or you could narrow it down by first making sure it's an mm bug and THEN if
uffd in repro include uffd people?

>
> That's why we mostly rely on stack traces to identify subsystems.

Right yeah.

Cheers, Lorenzo
Reply all
Reply to author
Forward
0 new messages