From nobody Thu Apr 9 14:10:25 2026 Received: from mail-yw1-f172.google.com (mail-yw1-f172.google.com [209.85.128.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7C73735893 for ; Sun, 8 Mar 2026 00:15:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772928909; cv=none; b=pb/pWZn7zV7KCIeWOa9iEzAli1kRUckoF/7fJTf3BZNmz2OLjduIcPN0+JvMXYld02J6lWf9q8RsrULPR8itDdKDFF4Fmfbw4/RKLIMiyj3jcvMs3nn4pzYaSjKt3KNCYUTNqh6cWnIbUxsS6ttXSjXWUzKeAkJ+qwDmwIiT5pE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772928909; c=relaxed/simple; bh=FNz4mqUtJvniaS740HIZmjIeq6NhnHImvn1ePA1cD3U=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=gqI2atQniHQo8uVgaAZrFI8Th/g8IcCguLfL8eaUvfRE7HmjwyAEjsMs5NkyNu78FWHB+cokWwndsBlMq55vsmE42ofvKsxahkRdpko+OqJCjYKsfleDcaZ4FoTMg2gEOQ6kdiao+q7puh2E/yXgyccG6eWyGc700qs+9KF224w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=sung-woo.kim; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.128.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=sung-woo.kim Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-yw1-f172.google.com with SMTP id 00721157ae682-793fdbb8d3aso127496967b3.3 for ; Sat, 07 Mar 2026 16:15:06 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772928905; x=1773533705; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=SDVoImbCMyrTI+fckI2KesjRHDf+Y2Y+sy8o597R4xM=; b=VrVHDA4ntouwoKNPGh6kus7Xv0wIx2v5pLUA4yzVZ9mRDYUL6k1LiPUU0c41lKPjxQ HP2StSLY1xDK1pFD4C86CB4zNSgLE8kVyyY/STaI7cApRDpmaGNZTaCuYX/uGYzJtpWp /04WcgDC9rhEggLk/qH79tjRXJzAck9pFXA6QWDZIBY+G9VPIY+vXXF7ObHpIGCy7vL9 1G6ItI568s+VDdAbw11kzMiQnnjLqQtT1uOQ4BWX75jJmNZfaOTUuUeSDl1ifZzEabSD x9jb3AqJEoJpjpxvWmrPh88kclQbrAfRWd8OQtTbJJHRdIo6Rhp5lRcoWLn+DcVp/RHp UUAA== X-Forwarded-Encrypted: i=1; AJvYcCXLAIpNAHDI2ST2G5lG05tZGpqS8CFDxXiIKCznN1sirvR7NrJikBNJgg/O8RJbuDEpDlZn/dMw8TubVp0=@vger.kernel.org X-Gm-Message-State: AOJu0Yz7+a1oVjLY8qb2GRwY5Ub6r7EWZipDhrlPhMxGUJuVY9dSQ6Ii wyqKZuv5f/UYr3PgOYWyc45pIb1AyriZB8Qi8RTXotckeoFaCPTmJ2n8 X-Gm-Gg: ATEYQzz6KuL6M6DQ5oujV28okkGOCfPgbB/SO/pNKr2BWTsKY1EuD1XROw8fILK4xi1 uzWKtsjeY5sSF4hm73IF1ZJoRgOH8LfCn/fLil/A6nWnjIQwmWDTWgF9zpwXrfRBp8JBwbHGcQk 4wXpl7zkA5PJZPB9+6Lj8LBJtfRB07Qbv5+UqpbpY4EwY5YfqE+MFKE5fcFGFqyoo01JvFuEFzB 2/DAJHvCzdJi7WnEDLJ54LviBoP5wrZ/TUMwLl4CNFRwcAQypAagp1b8mUrJbWTQSkeItqLGlxS UJsXNqiN0CVmiVaKvp2y1PsryusoYLrq+/9+Ug3QE5P9UdLRCbefnXVOUhvtzk20KNupUjqSihQ b9ZDfHZnxzbr4VY1znLqm14XP2MGxbvlhDnXXWcPkikK9+ZEg75i9NoJcZjjpOirLmTcXh6Su+z cyVHCxW1O/nw== X-Received: by 2002:a05:690c:a:b0:798:6d23:17d3 with SMTP id 00721157ae682-798dd7d130dmr62437067b3.61.1772928905338; Sat, 07 Mar 2026 16:15:05 -0800 (PST) Received: from tofu.. ([128.210.0.165]) by smtp.googlemail.com with ESMTPSA id 00721157ae682-798decdd38dsm25665067b3.21.2026.03.07.16.15.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 07 Mar 2026 16:15:04 -0800 (PST) From: Sungwoo Kim To: Jens Axboe , Keith Busch Cc: Sungwoo Kim , Chao Shi , Weidong Zhu , Dave Tian , linux-block@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] Fix null-ptr-deref in bio_integrity_map_user() Date: Sat, 7 Mar 2026 19:13:58 -0500 Message-ID: <20260308001358.1675543-2-iam@sung-woo.kim> X-Mailer: git-send-email 2.47.3 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A malicious user program can request large user-memory pinning via ioctl with a large metadata_len. However, this does not guarantee that all requested memory will be pinned. Pinning may partially succeed and return the number of bytes that were actually pinned, which may not match the requested size. In this case, only the addresses of the pinned pages are valid. The current implementation does not handle partial pinning and incorrectly assumes that all pages in the range [0, nr_vecs) are valid. This can lead to a null-pointer dereference because pages[n] may refer to an unpinned memory range. To fix this, add a check to verify that all requested pages are successfully pinned. Pinning all pages is required to copy user data. KASAN splat: Syzkaller hit 'general protection fault in bio_integrity_map_user' bug. nvme nvme0: Command: 80f60320000000000300000000c9ffffb38ab5410000000070693a= a0ffffffffb00e619dffffffff80f6032000000000b38ab5410000000070fc38a0ffffffff nvme nvme0: Command: 80f60320000000000300000000c9ffffb38ab5410000000070693a= a0ffffffffb00e619dffffffff80f6032000000000b38ab5410000000070fc38a0ffffffff nvme nvme0: 2/0/0 default/read/poll queues Oops: general protection fault, probably for non-canonical address 0xdffffc= 0000000001: 0000 [#1] PREEMPT SMP KASAN PTI KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f] CPU: 0 UID: 0 PID: 280 Comm: syz-executor294 Not tainted 6.11.0-dirty #6 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga= 6ed6b701f0a-prebuilt.qemu.org 04/01/2014 RIP: 0010:_compound_head home/wukong/fuzznvme/linux/./include/linux/page-fl= ags.h:240 [inline] RIP: 0010:bvec_from_pages home/wukong/fuzznvme/linux/block/bio-integrity.c:= 290 [inline] RIP: 0010:bio_integrity_map_user+0x5a3/0x11e0 home/wukong/fuzznvme/linux/bl= ock/bio-integrity.c:345 Code: 4c 89 e0 48 c1 e8 03 80 3c 30 00 0f 85 4b 0a 00 00 48 be 00 00 00 00 = 00 fc ff df 49 8b 1c 24 48 8d 7b 08 48 89 f8 48 c1 e8 03 <80> 3c 30 00 0f 8= 5 35 0a 00 00 48 8b 43 08 31 ff 49 89 c5 48 89 44 RSP: 0018:ffffc900010cf4f0 EFLAGS: 00010202 RAX: 0000000000000001 RBX: 0000000000000000 RCX: 000000000000f761 RDX: ffff888006cae600 RSI: dffffc0000000000 RDI: 0000000000000008 RBP: ffffc900010cf7d0 R08: ffff888006cae600 R09: ffffed1000e0db95 R10: ffff88800706dcaf R11: ffff888006a31a00 R12: ffff888006a31a08 R13: 0000000000000740 R14: ffff888006a31a00 R15: 0000000000000001 FS: 0000555587e483c0(0000) GS:ffff88806ce00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000002002f8c0 CR3: 000000000719a000 CR4: 00000000000006f0 Call Trace: nvme_map_user_request+0x4b6/0x5e0 home/wukong/fuzznvme/linux/drivers/nvme/= host/ioctl.c:149 nvme_submit_user_cmd+0x2e8/0x3c0 home/wukong/fuzznvme/linux/drivers/nvme/h= ost/ioctl.c:185 nvme_user_cmd.constprop.0+0x35b/0x540 home/wukong/fuzznvme/linux/drivers/n= vme/host/ioctl.c:325 nvme_ns_ioctl+0x11e/0x1c0 home/wukong/fuzznvme/linux/drivers/nvme/host/ioc= tl.c:570 nvme_ioctl+0x147/0x1d0 home/wukong/fuzznvme/linux/drivers/nvme/host/ioctl.= c:605 blkdev_ioctl+0x28c/0x6c0 home/wukong/fuzznvme/linux/block/ioctl.c:676 vfs_ioctl home/wukong/fuzznvme/linux/fs/ioctl.c:51 [inline] __do_sys_ioctl home/wukong/fuzznvme/linux/fs/ioctl.c:907 [inline] __se_sys_ioctl home/wukong/fuzznvme/linux/fs/ioctl.c:893 [inline] __x64_sys_ioctl+0x1bc/0x230 home/wukong/fuzznvme/linux/fs/ioctl.c:893 x64_sys_call+0x1209/0x20d0 home/wukong/fuzznvme/linux/./arch/x86/include/g= enerated/asm/syscalls_64.h:17 do_syscall_x64 home/wukong/fuzznvme/linux/arch/x86/entry/common.c:52 [inli= ne] do_syscall_64+0x6f/0x110 home/wukong/fuzznvme/linux/arch/x86/entry/common.= c:83 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7f5b3d8e98bd Code: c3 e8 a7 1f 00 00 0f 1f 80 00 00 00 00 f3 0f 1e fa 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 f= f 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fffd1c0e988 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00000000000f4240 RCX: 00007f5b3d8e98bd RDX: 000000002003f680 RSI: 00000000c0484e43 RDI: 0000000000000003 RBP: 0000000000000000 R08: 00007f5b3d93eb4d R09: 00007f5b3d93eb4d R10: 00007f5b3d93eb4d R11: 0000000000000246 R12: 0000000000000001 R13: 00007fffd1c0ebe8 R14: 00007fffd1c0e9b0 R15: 00007fffd1c0e9a0 Modules linked in: Oops: general protection fault, probably for non-canonical address 0xdffffc= 0000000001: 0000 [#2] PREEMPT SMP KASAN PTI Fixes: 492c5d455969 (block: bio-integrity: directly map user buffers) Acked-by: Chao Shi Acked-by: Weidong Zhu Acked-by: Dave Tian Signed-off-by: Sungwoo Kim --- block/bio-integrity.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/block/bio-integrity.c b/block/bio-integrity.c index 96a265390..7d633f39e 100644 --- a/block/bio-integrity.c +++ b/block/bio-integrity.c @@ -341,6 +341,23 @@ int bio_integrity_map_user(struct bio *bio, void __use= r *ubuf, ssize_t bytes, ret =3D iov_iter_extract_pages(&iter, &pages, bytes, nr_vecs, 0, &offset); if (unlikely(ret < 0)) goto free_bvec; + if (unlikely(ret !=3D bytes)) { + /* + * Not all pages could be pinned. This can happen when + * pin_user_pages_fast() returns fewer pages than requested. + * All pages must be pinned to copy user data, so unpin + * whatever we got and fail. + */ + int npinned =3D DIV_ROUND_UP(offset + ret, PAGE_SIZE); + int i; + + for (i =3D 0; i < npinned; i++) + unpin_user_page(pages[i]); + if (pages !=3D stack_pages) + kvfree(pages); + ret =3D -EFAULT; + goto free_bvec; + } =20 nr_bvecs =3D bvec_from_pages(bvec, pages, nr_vecs, bytes, offset); if (pages !=3D stack_pages) --=20 2.47.3