mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] dma-buf/udmabuf: avoid oversized kvmalloc in init_udmabuf()
@ 2026-09-18  1:34 Jiakai Xu
  2026-09-18 10:17 ` Christian König
  0 siblings, 1 reply; 3+ messages in thread
From: Jiakai Xu @ 2026-09-18  1:34 UTC (permalink / raw)
  To: Gerd Hoffmann, Vivek Kasireddy, Sumit Semwal,
	Christian König, dri-devel
  Cc: Huan Yang, Robert Mader, linux-media, linaro-mm-sig,
	linux-kernel, Jiakai Xu

init_udmabuf() allocates two pointer arrays with one entry per page of
the created buffer.  Since commit 1c0844c6184e ("udmabuf: change folios
array from kmalloc to kvmalloc") these arrays are allocated with
kvmalloc(), which warns and fails when the requested size exceeds
INT_MAX bytes.

With the default size limit of 64 MB the largest possible request was
far below that threshold, but commit 44e9eb5a7621 ("dma-buf/udmabuf:
Disable the size limit by default") raised the limit to INT_MAX MB.
With 4K pages, creating a buffer of more than INT_MAX / 8 pages (about
1 TB of pinned memory) now makes kvmalloc() hit its "crazy size"
WARN_ON_ONCE(), which is trivially triggerable from unprivileged users
through the UDMABUF_CREATE ioctls:

  WARNING: CPU: 0 PID: 412 at mm/slub.c:7021 __kvmalloc_node_noprof
  Call Trace:
   udmabuf_create
   udmabuf_ioctl_create_list

Fix it by rejecting buffers whose page count exceeds what the pointer
arrays can address before calling init_udmabuf(), returning -EINVAL.

Fixes: 1c0844c6184e ("udmabuf: change folios array from kmalloc to kvmalloc")
Fixes: 44e9eb5a7621 ("dma-buf/udmabuf: Disable the size limit by default")
Signed-off-by: Jiakai Xu <xujiakai24@mails.ucas.ac.cn>
---
 drivers/dma-buf/udmabuf.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index df6dd00462423..25984e75d7ff3 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -383,6 +383,14 @@ static long udmabuf_create(struct miscdevice *device,
 	if (!pgcnt)
 		goto err_noinit;
 
+	/*
+	 * init_udmabuf() allocates two arrays of pointers, one entry per
+	 * page, with kvmalloc(), which cannot handle sizes larger than
+	 * INT_MAX bytes.
+	 */
+	if (pgcnt > INT_MAX / sizeof(struct page *))
+		goto err_noinit;
+
 	ret = init_udmabuf(ubuf, pgcnt);
 	if (ret)
 		goto err;
-- 
2.34.1


-- 
Below is the crash report:
------------[ cut here ]------------
WARNING: mm/slub.c:7013 at __kvmalloc_node_noprof+0x516/0x5d0 home/zzzrrll/tmp/kf_src/linux-7.3-rc2/mm/slub.c:7013, CPU#0: syz.5.27938/167363
Modules linked in:
CPU: 0 UID: 0 PID: 167363 Comm: syz.5.27938 Tainted: G        W    L      7.3.0-rc2 #1 PREEMPT(full) 
Tainted: [W]=WARN, [L]=SOFTLOCKUP
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
RIP: 0010:__kvmalloc_node_noprof+0x516/0x5d0 home/zzzrrll/tmp/kf_src/linux-7.3-rc2/mm/slub.c:7013
Code: 05 bf fa 2d 08 49 8b 0f c6 04 08 00 65 48 ff 0d 90 fa 2d 08 0f 85 4c fd ff ff e8 05 43 8c ff e9 42 fd ff ff e8 9b 86 0e 04 90 <0f> 0b 90 31 db e9 d2 fe ff ff f3 0f 1e fa 65 8b 05 8d fa 2d 08 89
RSP: 0018:ffffc90002bc3cf8 EFLAGS: 00010246
RAX: 0000000000000100 RBX: 0000000000000000 RCX: 0000008000000000
RDX: 0000008000000000 RSI: 0000000000000000 RDI: ffffffff835e3226
RBP: 00000000ffffffff R08: 00000000000028c0 R09: 00000000ffffffff
R10: 0000000000000006 R11: 0000000000000002 R12: 0000008000000000
R13: 00000000000028c0 R14: 0000001000000000 R15: 0000008000000000
FS:  00007fc89ae45640(0000) GS:ffff8880f3de4000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000000110c2ff305 CR3: 000000002b3d4000 CR4: 0000000000752ef0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000006000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
PKRU: 80000000
Call Trace:
 <TASK>
 init_udmabuf home/zzzrrll/tmp/kf_src/linux-7.3-rc2/drivers/dma-buf/udmabuf.c:193 [inline]
 udmabuf_create+0x1b6/0x750 home/zzzrrll/tmp/kf_src/linux-7.3-rc2/drivers/dma-buf/udmabuf.c:386
 udmabuf_ioctl_create home/zzzrrll/tmp/kf_src/linux-7.3-rc2/drivers/dma-buf/udmabuf.c:465 [inline]
 udmabuf_ioctl+0x132/0x1d0 home/zzzrrll/tmp/kf_src/linux-7.3-rc2/drivers/dma-buf/udmabuf.c:496
 vfs_ioctl home/zzzrrll/tmp/kf_src/linux-7.3-rc2/fs/ioctl.c:51 [inline]
 __do_sys_ioctl home/zzzrrll/tmp/kf_src/linux-7.3-rc2/fs/ioctl.c:597 [inline]
 __se_sys_ioctl+0xbc/0x130 home/zzzrrll/tmp/kf_src/linux-7.3-rc2/fs/ioctl.c:583
 do_syscall_x64 home/zzzrrll/tmp/kf_src/linux-7.3-rc2/arch/x86/entry/syscall_64.c:61 [inline]
 do_syscall_64+0x12b/0x350 home/zzzrrll/tmp/kf_src/linux-7.3-rc2/arch/x86/entry/syscall_64.c:84
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x590d6d
Code: 02 b8 ff ff ff ff c3 66 0f 1f 44 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 ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fc89ae44fd8 EFLAGS: 00000216 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 0000000000611e7f RCX: 0000000000590d6d
RDX: 00002000000023c0 RSI: 0000000040187542 RDI: 000000000000000a
RBP: 00007fc89ae45010 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000216 R12: 00007fc89ae45640
R13: 000000000000000b R14: 0000000000528d40 R15: 00007fc89ae25000
 </TASK>
---[ end trace 0000000000000000 ]---
---


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-09-19  8:21 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-18  1:34 [PATCH] dma-buf/udmabuf: avoid oversized kvmalloc in init_udmabuf() Jiakai Xu
2026-09-18 10:17 ` Christian König
2026-09-19  8:21   ` Kasireddy, Vivek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®