{"id":"DEBIAN-CVE-2025-21881","details":"In the Linux kernel, the following vulnerability has been resolved:  uprobes: Reject the shared zeropage in uprobe_write_opcode()  We triggered the following crash in syzkaller tests:    BUG: Bad page state in process syz.7.38  pfn:1eff3   page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1eff3   flags: 0x3fffff00004004(referenced|reserved|node=0|zone=1|lastcpupid=0x1fffff)   raw: 003fffff00004004 ffffe6c6c07bfcc8 ffffe6c6c07bfcc8 0000000000000000   raw: 0000000000000000 0000000000000000 00000000fffffffe 0000000000000000   page dumped because: PAGE_FLAGS_CHECK_AT_FREE flag(s) set   Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014   Call Trace:    \u003cTASK\u003e    dump_stack_lvl+0x32/0x50    bad_page+0x69/0xf0    free_unref_page_prepare+0x401/0x500    free_unref_page+0x6d/0x1b0    uprobe_write_opcode+0x460/0x8e0    install_breakpoint.part.0+0x51/0x80    register_for_each_vma+0x1d9/0x2b0    __uprobe_register+0x245/0x300    bpf_uprobe_multi_link_attach+0x29b/0x4f0    link_create+0x1e2/0x280    __sys_bpf+0x75f/0xac0    __x64_sys_bpf+0x1a/0x30    do_syscall_64+0x56/0x100    entry_SYSCALL_64_after_hwframe+0x78/0xe2     BUG: Bad rss-counter state mm:00000000452453e0 type:MM_FILEPAGES val:-1  The following syzkaller test case can be used to reproduce:    r2 = creat(&(0x7f0000000000)='./file0\\x00', 0x8)   write$nbd(r2, &(0x7f0000000580)=ANY=[], 0x10)   r4 = openat(0xffffffffffffff9c, &(0x7f0000000040)='./file0\\x00', 0x42, 0x0)   mmap$IORING_OFF_SQ_RING(&(0x7f0000ffd000/0x3000)=nil, 0x3000, 0x0, 0x12, r4, 0x0)   r5 = userfaultfd(0x80801)   ioctl$UFFDIO_API(r5, 0xc018aa3f, &(0x7f0000000040)={0xaa, 0x20})   r6 = userfaultfd(0x80801)   ioctl$UFFDIO_API(r6, 0xc018aa3f, &(0x7f0000000140))   ioctl$UFFDIO_REGISTER(r6, 0xc020aa00, &(0x7f0000000100)={{&(0x7f0000ffc000/0x4000)=nil, 0x4000}, 0x2})   ioctl$UFFDIO_ZEROPAGE(r5, 0xc020aa04, &(0x7f0000000000)={{&(0x7f0000ffd000/0x1000)=nil, 0x1000}})   r7 = bpf$PROG_LOAD(0x5, &(0x7f0000000140)={0x2, 0x3, &(0x7f0000000200)=ANY=[@ANYBLOB=\"1800000000120000000000000000000095\"], &(0x7f0000000000)='GPL\\x00', 0x7, 0x0, 0x0, 0x0, 0x0, '\\x00', 0x0, @fallback=0x30, 0xffffffffffffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, @void, @value}, 0x94)   bpf$BPF_LINK_CREATE_XDP(0x1c, &(0x7f0000000040)={r7, 0x0, 0x30, 0x1e, @val=@uprobe_multi={&(0x7f0000000080)='./file0\\x00', &(0x7f0000000100)=[0x2], 0x0, 0x0, 0x1}}, 0x40)  The cause is that zero pfn is set to the PTE without increasing the RSS count in mfill_atomic_pte_zeropage() and the refcount of zero folio does not increase accordingly. Then, the operation on the same pfn is performed in uprobe_write_opcode()-\u003e__replace_page() to unconditional decrease the RSS count and old_folio's refcount.  Therefore, two bugs are introduced:   1. The RSS count is incorrect, when process exit, the check_mm() report     error \"Bad rss-count\".   2. The reserved folio (zero folio) is freed when folio-\u003erefcount is zero,     then free_pages_prepare-\u003efree_page_is_bad() report error     \"Bad page state\".  There is more, the following warning could also theoretically be triggered:    __replace_page()     -\u003e ...       -\u003e folio_remove_rmap_pte()         -\u003e VM_WARN_ON_FOLIO(is_zero_folio(folio), folio)  Considering that uprobe hit on the zero folio is a very rare case, just reject zero old folio immediately after get_user_page_vma_remote().  [ mingo: Cleaned up the changelog ]","modified":"2026-09-01T16:06:10.274059864Z","published":"2025-03-27T15:15:56Z","upstream":["CVE-2025-21881"],"references":[{"type":"ADVISORY","url":"https://security-tracker.debian.org/tracker/CVE-2025-21881"}],"affected":[{"package":{"name":"linux","ecosystem":"Debian:12","purl":"pkg:deb/debian/linux?arch=source&distro=bookworm"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"6.1.133-1"}]}],"versions":["6.1.106-1","6.1.106-2","6.1.106-3","6.1.112-1","6.1.115-1","6.1.119-1","6.1.123-1","6.1.124-1","6.1.128-1","6.1.129-1","6.1.27-1","6.1.37-1","6.1.38-1","6.1.38-2","6.1.38-2~bpo11+1","6.1.38-3","6.1.38-4","6.1.38-4~bpo11+1","6.1.52-1","6.1.55-1","6.1.55-1~bpo11+1","6.1.64-1","6.1.66-1","6.1.67-1","6.1.69-1","6.1.69-1~bpo11+1","6.1.76-1","6.1.76-1~bpo11+1","6.1.82-1","6.1.85-1","6.1.90-1","6.1.90-1~bpo11+1","6.1.94-1","6.1.94-1~bpo11+1","6.1.98-1","6.1.99-1"],"ecosystem_specific":{"urgency":"not yet assigned"},"database_specific":{"source":"https://storage.googleapis.com/osv-test-debian-osv/debian-cve-osv/DEBIAN-CVE-2025-21881.json"}},{"package":{"name":"linux","ecosystem":"Debian:13","purl":"pkg:deb/debian/linux?arch=source&distro=trixie"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"6.12.19-1"}]}],"ecosystem_specific":{"urgency":"not yet assigned"},"database_specific":{"source":"https://storage.googleapis.com/osv-test-debian-osv/debian-cve-osv/DEBIAN-CVE-2025-21881.json"}},{"package":{"name":"linux","ecosystem":"Debian:14","purl":"pkg:deb/debian/linux?arch=source&distro=forky"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"6.12.19-1"}]}],"ecosystem_specific":{"urgency":"not yet assigned"},"database_specific":{"source":"https://storage.googleapis.com/osv-test-debian-osv/debian-cve-osv/DEBIAN-CVE-2025-21881.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H"}]}