general protection fault in vma_is_shmem

Status: upstream: reported C repro on 2022/08/21 06:14
Subsystems: io-uring mm
Labels: prio:high
[Documentation on labels]
Reported-by: syzbot+681bbbb80445ead3c040@syzkaller.appspotmail.com
Fix commit: mm/gup.c: Fix return value for __gup_longterm_locked()
Patched on: [ci-upstream-linux-next-kasan-gce-root], missing on: [ci-qemu-gce-upstream-auto ci-qemu-native-arm64-kvm ci-qemu-upstream ci-qemu-upstream-386 ci-qemu2-arm32 ci-qemu2-arm64 ci-qemu2-arm64-compat ci-qemu2-arm64-mte ci-qemu2-riscv64 ci-snapshot-upstream-root ci-upstream-bpf-kasan-gce ci-upstream-bpf-next-kasan-gce ci-upstream-gce-arm64 ci-upstream-gce-leak ci-upstream-kasan-badwrites-root ci-upstream-kasan-gce ci-upstream-kasan-gce-386 ci-upstream-kasan-gce-root ci-upstream-kasan-gce-selinux-root ci-upstream-kasan-gce-smack-root ci-upstream-kmsan-gce-386-root ci-upstream-kmsan-gce-root ci-upstream-net-kasan-gce ci-upstream-net-this-kasan-gce ci-upstream-rust-kasan-gce ci2-upstream-fs ci2-upstream-kcsan-gce ci2-upstream-usb]
First crash: 1547d, last: 1542d
Cause bisection: failed (error log, bisect log)
  
✨ AI-generated root cause summary:

In __gup_longterm_locked() (mm/gup.c), the return value of __get_user_pages_locked() (the number of successfully pinned pages) is stored in rc and subsequently overwritten by the return value of check_and_migrate_movable_pages(). When no pages require migration, check_and_migrate_movable_pages() returns 0, causing __gup_longterm_locked() to evaluate 'return rc ? rc : nr_pages;' and erroneously return nr_pages instead of the actual number of pages pinned. On a partial pin, callers like io_pin_pages() in io_uring/rsrc.c assume all nr_pages were pinned and iterate past the populated entries in vmas[], passing a NULL vma to vma_is_shmem() and causing a NULL pointer dereference.

▶ ▼ ✨ Full AI root cause analysis
Based on kernel commit 95d10484d66e:

Root Cause Analysis

1. Involved Functions, Structs, and Files


2. Technical Mechanism and Trigger Flow

  1. Buffer Registration in io_uring: Userspace registers a user buffer via io_uring_register (IORING_REGISTER_BUFFERS). In io_uring/rsrc.c:io_pin_pages(), the kernel calculates the total number of pages required (nr_pages = end - start), allocates pages and vmas arrays of size nr_pages, and calls:

    pret = pin_user_pages(ubuf, nr_pages, FOLL_WRITE | FOLL_LONGTERM, pages, vmas);
    
  2. GUP Call Handling in mm/gup.c: pin_user_pages() passes the request to __gup_longterm_locked():

    static long __gup_longterm_locked(struct mm_struct *mm,
                                      unsigned long start,
                                      unsigned long nr_pages,
                                      struct page **pages,
                                      struct vm_area_struct **vmas,
                                      unsigned int gup_flags)
    {
        unsigned int flags;
        long rc;
    ...
        flags = memalloc_pin_save();
        do {
            rc = __get_user_pages_locked(mm, start, nr_pages, pages, vmas,
                                         NULL, gup_flags);
            if (rc <= 0)
                break;
            rc = check_and_migrate_movable_pages(rc, pages, gup_flags);
        } while (rc == -EAGAIN);
        memalloc_pin_restore(flags);
    
        return rc ? rc : nr_pages;
    }
    
  3. Flawed Handling of Partial Pins:

    • If the requested virtual address range spans across an unmapped region or hits a mapping error, __get_user_pages_locked() performs a partial pin and returns rc (where 0 < rc < nr_pages). In this scenario, only the first rc elements of pages[] and vmas[] are populated.
    • check_and_migrate_movable_pages(rc, pages, gup_flags) is called on the rc pinned pages. If none of these pages need migration, it returns 0 (success).
    • The defect: rc is overwritten with 0 (the return value of check_and_migrate_movable_pages()), discarding the actual count of pinned pages (rc).
    • The loop condition while (rc == -EAGAIN) terminates because rc == 0.
    • At line 2086, the function evaluates return rc ? rc : nr_pages;. Because rc == 0, it evaluates to nr_pages and returns the full requested count nr_pages, falsely claiming that all requested pages were successfully pinned.
  4. Manifestation in Caller (io_pin_pages()):

    • io_pin_pages() checks whether all pages were pinned:
      if (pret == nr_pages) {
          for (i = 0; i < nr_pages; i++) {
              struct vm_area_struct *vma = vmas[i];
      
              if (vma_is_shmem(vma))
                  continue;
              ...
          }
      
    • Because pret == nr_pages evaluates to true, the loop iterates from 0 to nr_pages - 1.
    • For index i >= rc, vmas[i] was never populated by GUP and remains NULL (or uninitialized).
    • When vma_is_shmem(vma) is called with vma == NULL, it dereferences vma->vm_ops at offset 0x90 (return vma->vm_ops == &shmem_vm_ops;).
    • Under KASAN, checking shadow memory for 0x90 (0xdffffc0000000012) traps with a General Protection Fault (KASAN: null-ptr-deref in range [0x0000000000000090-0x0000000000000097]).
▶ ▼ ✨ AI Jobs (10)
ID Workflow Result Correct Bug Created Started Finished Revision
465f11a2 assessment-security DenialOfService: ✅ Exploitable: ✅ FilesystemTrigger: ❌ FuzzingArtifact: ❌ MemoryCorruption: ✅ NetworkNeedsSetup: ❌ NetworkTrigger: ❌ PeripheralTrigger: ❌ RemoteTrigger: ❌ Unprivileged: ✅ UserNamespace: ✅ VMGuestTrigger: ❌ VMHostTrigger: ❌ ❓ general protection fault in vma_is_shmem 2026/11/05 13:43 2026/11/05 13:43 2026/11/05 14:35 5cecaf1f
134b7c2e assessment-security 💥 general protection fault in vma_is_shmem 2026/10/05 16:16 2026/10/05 16:16 2026/10/05 16:28 1995e6c7
0959373f assessment-security 💥 general protection fault in vma_is_shmem 2026/09/04 11:49 2026/09/04 11:49 2026/09/04 12:04 801f0966
b7132c6b assessment-security 💥 general protection fault in vma_is_shmem 2026/08/05 00:07 2026/08/05 00:07 2026/08/05 00:07 d4abbeac
d4c9cbb7 assessment-security 💥 general protection fault in vma_is_shmem 2026/07/05 09:14 2026/07/05 09:14 2026/07/05 09:27 93f57954
4604dec7 assessment-security 💥 general protection fault in vma_is_shmem 2026/06/18 08:47 2026/06/18 08:47 2026/06/18 09:01 b62b3ded
7995b269 assessment-security 💥 general protection fault in vma_is_shmem 2026/06/10 04:33 2026/06/10 04:33 2026/06/10 04:49 c36c07f6
2603e8a6 assessment-security 💥 general protection fault in vma_is_shmem 2026/06/04 07:57 2026/06/04 07:57 2026/06/04 08:10 62fe1528
5d9e0c59 assessment-security 💥 general protection fault in vma_is_shmem 2026/06/02 05:57 2026/06/02 05:57 2026/06/02 06:21 1095583b
3333dffc assessment-security 💥 general protection fault in vma_is_shmem 2026/05/22 08:49 2026/05/22 08:49 2026/05/22 10:20 70ae9b03
▶ ▼ Discussions (1)
Title Replies (including bot) Last reply
[syzbot] general protection fault in vma_is_shmem 5 (6) 2022/08/31 09:40

Sample crash report:
general protection fault, probably for non-canonical address 0xdffffc0000000012: 0000 [#1] PREEMPT SMP KASAN
KASAN: null-ptr-deref in range [0x0000000000000090-0x0000000000000097]
CPU: 1 PID: 3607 Comm: syz-executor359 Not tainted 6.0.0-rc1-next-20220817-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/22/2022
RIP: 0010:vma_is_shmem+0x21/0x40 mm/shmem.c:254
Code: 73 02 e9 20 fc ff ff 66 90 53 48 89 fb e8 07 2c cf ff 48 8d bb 90 00 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 75 10 48 81 bb 90 00 00 00 20 8f f7 89 5b 0f 94 c0 c3
RSP: 0018:ffffc900037cfb68 EFLAGS: 00010206
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000
RDX: 0000000000000012 RSI: ffffffff81ace949 RDI: 0000000000000090
RBP: ffff888071b00720 R08: 0000000000000006 R09: 00000000000000e4
R10: 0000000000008001 R11: 0000000000000000 R12: 00000000000000e4
R13: ffff888071b00000 R14: dffffc0000000000 R15: 0000000000000000
FS:  0000555556ab5300(0000) GS:ffff8880b9b00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fa3c8f13260 CR3: 00000000718f5000 CR4: 00000000003506e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 <TASK>
 io_pin_pages+0x25f/0x430 io_uring/rsrc.c:1207
 io_sqe_buffer_register+0x14e/0x13b0 io_uring/rsrc.c:1254
 io_sqe_buffers_register.cold+0x351/0x445 io_uring/rsrc.c:1346
 __io_uring_register io_uring/io_uring.c:3711 [inline]
 __do_sys_io_uring_register+0x96d/0x1110 io_uring/io_uring.c:3878
 do_syscall_x64 arch/x86/entry/common.c:50 [inline]
 do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x7f548fcdfbb9
Code: 28 c3 e8 2a 14 00 00 66 2e 0f 1f 84 00 00 00 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 c0 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ffc644b88f8 EFLAGS: 00000246 ORIG_RAX: 00000000000001ab
RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007f548fcdfbb9
RDX: 0000000020000080 RSI: 0000000000000000 RDI: 0000000000000003
RBP: 00007f548fca3d60 R08: 0000000010000000 R09: 0000000000000000
R10: 0000000000000001 R11: 0000000000000246 R12: 00007f548fca3df0
R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
 </TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:vma_is_shmem+0x21/0x40 mm/shmem.c:254
Code: 73 02 e9 20 fc ff ff 66 90 53 48 89 fb e8 07 2c cf ff 48 8d bb 90 00 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 75 10 48 81 bb 90 00 00 00 20 8f f7 89 5b 0f 94 c0 c3
RSP: 0018:ffffc900037cfb68 EFLAGS: 00010206
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000
RDX: 0000000000000012 RSI: ffffffff81ace949 RDI: 0000000000000090
RBP: ffff888071b00720 R08: 0000000000000006 R09: 00000000000000e4
R10: 0000000000008001 R11: 0000000000000000 R12: 00000000000000e4
R13: ffff888071b00000 R14: dffffc0000000000 R15: 0000000000000000
FS:  0000555556ab5300(0000) GS:ffff8880b9b00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fa3c8f13260 CR3: 00000000718f5000 CR4: 00000000003506e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
----------------
Code disassembly (best guess):
   0:	73 02                	jae    0x4
   2:	e9 20 fc ff ff       	jmpq   0xfffffc27
   7:	66 90                	xchg   %ax,%ax
   9:	53                   	push   %rbx
   a:	48 89 fb             	mov    %rdi,%rbx
   d:	e8 07 2c cf ff       	callq  0xffcf2c19
  12:	48 8d bb 90 00 00 00 	lea    0x90(%rbx),%rdi
  19:	48 b8 00 00 00 00 00 	movabs $0xdffffc0000000000,%rax
  20:	fc ff df
  23:	48 89 fa             	mov    %rdi,%rdx
  26:	48 c1 ea 03          	shr    $0x3,%rdx
* 2a:	80 3c 02 00          	cmpb   $0x0,(%rdx,%rax,1) <-- trapping instruction
  2e:	75 10                	jne    0x40
  30:	48 81 bb 90 00 00 00 	cmpq   $0xffffffff89f78f20,0x90(%rbx)
  37:	20 8f f7 89
  3b:	5b                   	pop    %rbx
  3c:	0f 94 c0             	sete   %al
  3f:	c3                   	retq

Crashes (28):
Time Kernel Commit Syzkaller Config Log Report Syz repro C repro VM info Assets (help?) Manager Title
2022/08/17 15:07 linux-next 95d10484d66e 4e72d229 .config strace log report syz C ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/22 18:54 linux-next 8755ae45a9e8 26a13b38 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/22 12:25 linux-next 8755ae45a9e8 26a13b38 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/22 06:46 linux-next 8755ae45a9e8 26a13b38 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/22 06:46 linux-next 8755ae45a9e8 26a13b38 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/21 20:04 linux-next 8755ae45a9e8 26a13b38 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/20 18:19 linux-next 8755ae45a9e8 26a13b38 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/20 08:52 linux-next 8755ae45a9e8 26a13b38 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/20 08:51 linux-next 8755ae45a9e8 26a13b38 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/19 21:42 linux-next 8755ae45a9e8 26a13b38 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/19 13:49 linux-next 8755ae45a9e8 26a13b38 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/19 11:55 linux-next 8755ae45a9e8 26a13b38 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/19 11:21 linux-next 8755ae45a9e8 26a13b38 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/19 10:52 linux-next 8755ae45a9e8 26a13b38 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/19 10:42 linux-next 8755ae45a9e8 26a13b38 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/19 10:42 linux-next 8755ae45a9e8 26a13b38 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/18 15:58 linux-next 5b6a4bf680d6 d58e263f .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/18 15:36 linux-next 5b6a4bf680d6 d58e263f .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/18 11:46 linux-next 5b6a4bf680d6 d58e263f .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/18 10:53 linux-next 5b6a4bf680d6 d58e263f .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/17 21:33 linux-next 95d10484d66e 4e72d229 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/17 21:33 linux-next 95d10484d66e 4e72d229 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/17 12:35 linux-next 95d10484d66e 4e72d229 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/17 11:52 linux-next 95d10484d66e 4e72d229 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/17 10:02 linux-next 95d10484d66e 4e72d229 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/17 08:27 linux-next 95d10484d66e 4e72d229 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/17 08:22 linux-next 95d10484d66e 4e72d229 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
2022/08/17 06:06 linux-next 95d10484d66e 4e72d229 .config console log report info ci-upstream-linux-next-kasan-gce-root general protection fault in vma_is_shmem
* Struck through repros no longer work on HEAD.