* [PATCH] ublk: use unchecked copy helpers for bio page data
@ 2026-03-28 13:42 Ming Lei
2026-03-28 17:40 ` Caleb Sander Mateos
0 siblings, 1 reply; 3+ messages in thread
From: Ming Lei @ 2026-03-28 13:42 UTC (permalink / raw)
To: Jens Axboe, linux-block; +Cc: Caleb Sander Mateos, Ming Lei
Bio pages may originate from slab caches that lack SLAB_USERCOPY
(e.g. jbd2 frozen metadata buffers allocated via jbd2_alloc()).
When CONFIG_HARDENED_USERCOPY is enabled, copy_to_iter() calls
check_copy_size() which rejects these slab pages, triggering a
kernel BUG in usercopy_abort().
This is a false positive: the data is ordinary block I/O content —
the same data the loop/nbd driver writes to its backing file via
vfs_iter_write(). The bvec length is always trusted, so the size
check in check_copy_size() is not needed either.
Switch to _copy_to_iter()/_copy_from_iter() which skip the
check_copy_size() wrapper while the underlying copy_to_user()
remains unchanged.
Fixes: 2299ceec364e ("ublk: use copy_{to,from}_iter() for user copy")
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
drivers/block/ublk_drv.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index 06ba8b441e5f..5f4a53216619 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -1322,10 +1322,18 @@ static bool ublk_copy_user_bvec(const struct bio_vec *bv, unsigned *offset,
len = bv->bv_len - *offset;
bv_buf = kmap_local_page(bv->bv_page) + bv->bv_offset + *offset;
+ /*
+ * Bio pages may originate from slab caches without SLAB_USERCOPY
+ * (e.g. jbd2 frozen metadata buffers). This is the same data that
+ * the loop driver writes to its backing file — no exposure risk.
+ * The bvec length is always trusted, so the size check in
+ * check_copy_size() is not needed either. Use the unchecked
+ * helpers to avoid false positives on slab pages.
+ */
if (dir == ITER_DEST)
- copied = copy_to_iter(bv_buf, len, uiter);
+ copied = _copy_to_iter(bv_buf, len, uiter);
else
- copied = copy_from_iter(bv_buf, len, uiter);
+ copied = _copy_from_iter(bv_buf, len, uiter);
kunmap_local(bv_buf);
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] ublk: use unchecked copy helpers for bio page data
2026-03-28 13:42 [PATCH] ublk: use unchecked copy helpers for bio page data Ming Lei
@ 2026-03-28 17:40 ` Caleb Sander Mateos
2026-03-29 14:44 ` Ming Lei
0 siblings, 1 reply; 3+ messages in thread
From: Caleb Sander Mateos @ 2026-03-28 17:40 UTC (permalink / raw)
To: Ming Lei; +Cc: Jens Axboe, linux-block
On Sat, Mar 28, 2026 at 6:43 AM Ming Lei <ming.lei@redhat.com> wrote:
>
> Bio pages may originate from slab caches that lack SLAB_USERCOPY
What is SLAB_USERCOPY? The only references to it I can find are in
comments in commit aa981a665d587 ("lkdtm: add usercopy tests").
Best,
Caleb
> (e.g. jbd2 frozen metadata buffers allocated via jbd2_alloc()).
> When CONFIG_HARDENED_USERCOPY is enabled, copy_to_iter() calls
> check_copy_size() which rejects these slab pages, triggering a
> kernel BUG in usercopy_abort().
>
> This is a false positive: the data is ordinary block I/O content —
> the same data the loop/nbd driver writes to its backing file via
> vfs_iter_write(). The bvec length is always trusted, so the size
> check in check_copy_size() is not needed either.
>
> Switch to _copy_to_iter()/_copy_from_iter() which skip the
> check_copy_size() wrapper while the underlying copy_to_user()
> remains unchanged.
>
> Fixes: 2299ceec364e ("ublk: use copy_{to,from}_iter() for user copy")
> Signed-off-by: Ming Lei <ming.lei@redhat.com>
> ---
> drivers/block/ublk_drv.c | 12 ++++++++++--
> 1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
> index 06ba8b441e5f..5f4a53216619 100644
> --- a/drivers/block/ublk_drv.c
> +++ b/drivers/block/ublk_drv.c
> @@ -1322,10 +1322,18 @@ static bool ublk_copy_user_bvec(const struct bio_vec *bv, unsigned *offset,
>
> len = bv->bv_len - *offset;
> bv_buf = kmap_local_page(bv->bv_page) + bv->bv_offset + *offset;
> + /*
> + * Bio pages may originate from slab caches without SLAB_USERCOPY
> + * (e.g. jbd2 frozen metadata buffers). This is the same data that
> + * the loop driver writes to its backing file — no exposure risk.
> + * The bvec length is always trusted, so the size check in
> + * check_copy_size() is not needed either. Use the unchecked
> + * helpers to avoid false positives on slab pages.
> + */
> if (dir == ITER_DEST)
> - copied = copy_to_iter(bv_buf, len, uiter);
> + copied = _copy_to_iter(bv_buf, len, uiter);
> else
> - copied = copy_from_iter(bv_buf, len, uiter);
> + copied = _copy_from_iter(bv_buf, len, uiter);
>
> kunmap_local(bv_buf);
>
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] ublk: use unchecked copy helpers for bio page data
2026-03-28 17:40 ` Caleb Sander Mateos
@ 2026-03-29 14:44 ` Ming Lei
0 siblings, 0 replies; 3+ messages in thread
From: Ming Lei @ 2026-03-29 14:44 UTC (permalink / raw)
To: Caleb Sander Mateos; +Cc: Jens Axboe, linux-block
On Sat, Mar 28, 2026 at 10:40:31AM -0700, Caleb Sander Mateos wrote:
> On Sat, Mar 28, 2026 at 6:43 AM Ming Lei <ming.lei@redhat.com> wrote:
> >
> > Bio pages may originate from slab caches that lack SLAB_USERCOPY
>
> What is SLAB_USERCOPY? The only references to it I can find are in
> comments in commit aa981a665d587 ("lkdtm: add usercopy tests").
>
Oops, I should have included the panic log here:
[ 41.604744] usercopy: Kernel memory exposure attempt detected from SLUB object 'jbd2_1k' (offset 0, size 1024)!
[ 41.607063] ------------[ cut here ]------------
[ 41.607290] kernel BUG at mm/usercopy.c:102!
[ 41.607502] Oops: invalid opcode: 0000 [#1] SMP NOPTI
[ 41.607794] CPU: 0 UID: 0 PID: 2020 Comm: kublk Not tainted 7.0.0-rc3_next+ #616 PREEMPT(full)
[ 41.608261] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-8.fc42 06/10/2025
[ 41.608722] RIP: 0010:usercopy_abort+0x7a/0x7c
[ 41.608995] Code: 48 c7 c6 ab 55 2c 8b eb 0e 48 c7 c7 b0 92 2e 8b 48 c7 c6 b9 87 2b 8b 52 48 89 fa 48 c7 c7 30 73 1f 8b 50 41 52 e8 66 25 fe ff <0f> 0b 48 89 d9 49 89 e8 44 89 f2 31 f6 48 29 c1 48 c7 c7 00 56 2c
[ 41.609985] RSP: 0018:ffffd3dcca79fae0 EFLAGS: 00010246
[ 41.610286] RAX: 0000000000000063 RBX: ffff8d87ec655000 RCX: 0000000000000000
[ 41.610707] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff8d87b5c1d440
[ 41.611111] RBP: 0000000000000400 R08: 0000000000000000 R09: 00000000fffeffff
[ 41.611556] R10: ffffffff8bc8c040 R11: ffffd3dcca79f968 R12: ffff8d87ec655400
[ 41.611913] R13: 0000000000000000 R14: 0000000000000001 R15: ffff8d85c400b000
[ 41.612375] FS: 00007f2ef3f066c0(0000) GS:ffff8d8828a82000(0000) knlGS:0000000000000000
[ 41.612832] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 41.613186] CR2: 00007f2efc137000 CR3: 000000032c7f2006 CR4: 0000000000772ef0
[ 41.613623] PKRU: 55555554
[ 41.613811] Call Trace:
[ 41.613973] <TASK>
[ 41.614108] __check_heap_object+0xb8/0xd0
[ 41.614345] __check_object_size+0x1b8/0x250
[ 41.614639] ublk_copy_user_bvec.isra.0+0x65/0xf0 [ublk_drv]
[ 41.614981] ublk_copy_user_pages.isra.0+0xc5/0x130 [ublk_drv]
[ 41.615360] ublk_start_io+0xff/0x160 [ublk_drv]
[ 41.615669] ublk_dispatch_req+0x99/0x240 [ublk_drv]
[ 41.615969] ublk_cmd_list_tw_cb+0x2d/0x40 [ublk_drv]
[ 41.616248] __io_run_local_work_loop+0x7c/0x80
[ 41.616449] __io_run_local_work+0x159/0x230
[ 41.616634] io_run_local_work+0x31/0x50
[ 41.616977] io_cqring_wait+0x28e/0x680
[ 41.617292] ? __io_issue_sqe+0x3b/0x1b0
[ 41.617607] ? __pfx_io_wake_function+0x10/0x10
[ 41.617894] __do_sys_io_uring_enter+0x601/0x8b0
[ 41.618183] do_syscall_64+0x11c/0x15d0
[ 41.618443] ? switch_fpu_return+0x56/0xf0
[ 41.618719] ? do_syscall_64+0x2d6/0x15d0
[ 41.618994] ? do_syscall_64+0x11c/0x15d0
[ 41.619262] ? do_syscall_64+0x11c/0x15d0
[ 41.619525] ? clear_bhb_loop+0x30/0x80
[ 41.619785] ? clear_bhb_loop+0x30/0x80
[ 41.620049] ? clear_bhb_loop+0x30/0x80
[ 41.620302] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 41.620598] RIP: 0033:0x7f2f045876fc
[ 41.620853] Code: 0f b6 c0 48 8b 79 20 8b 3f 83 e7 01 44 0f 45 d0 41 83 ca 01 8b b9 cc 00 00 00 45 31 c0 41 b9 08 00 00 00 b8 aa 01 00 00 0f 05 <c3> 0f 1f 00 89 30 eb 9b 0f 1f 40 00 41 f6 c2 04 74 32 44 89 d0 41
[ 41.621710] RSP: 002b:00007f2ef3f05c38 EFLAGS: 00000246 ORIG_RAX: 00000000000001aa
[ 41.622112] RAX: ffffffffffffffda RBX: 00007f2ef3f05cc0 RCX: 00007f2f045876fc
[ 41.622493] RDX: 0000000000000001 RSI: 0000000000000001 RDI: 0000000000000000
[ 41.622901] RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000008
[ 41.623281] R10: 0000000000000011 R11: 0000000000000246 R12: 0000000000000002
[ 41.623649] R13: 0000000000000001 R14: 00007f2f0410c558 R15: 00000000000a6042
[ 41.624015] </TASK>
[ 41.624239] Modules linked in: iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi target_core_pscsi target_core_file target_core_iblock iscsi_target_mod target_core_mod isofs nfsd auth_rpcgss nfs_acl lockd grace nfs_localio sunrpc vfat fat intel_rapl_msr intel_rapl_common kvm_intel kvm ppdev virtio_gpu virtio_net parport_pc parport net_failover i2c_i801 rapl i2c_smbus failover virtio_dma_buf bochs joydev vfio_pci vfio_pci_core vfio_iommu_type1 vfio irqbypass ublk_drv configs loop zram nvme uas nvme_core usb_storage virtio_scsi ghash_clmulni_intel virtio_blk nvme_keyring nvme_auth serio_raw scsi_dh_rdac scsi_dh_emc scsi_dh_alua fuse dm_multipath qemu_fw_cfg
[ 41.626838] Dumping ftrace buffer:
[ 41.627085] (ftrace buffer empty)
[ 41.627354] ---[ end trace 0000000000000000 ]---
Thanks,
Ming
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-03-29 14:44 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-28 13:42 [PATCH] ublk: use unchecked copy helpers for bio page data Ming Lei
2026-03-28 17:40 ` Caleb Sander Mateos
2026-03-29 14:44 ` Ming Lei
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox