[PATCH] dma-buf/udmabuf: don't warn on oversized allocation requests

From: Priyanka Mani

Date: Fri Sep 18 2026 - 04:29:39 EST


udmabuf_create() derives the number of pages to allocate directly from
the size supplied by userspace, bounded only by the size_limit_mb module
parameter. Since commit 44e9eb5a7621 ("dma-buf/udmabuf: Disable the size
limit by default") that parameter defaults to INT_MAX, which puts the
page count limit at roughly 5.5e11 pages, i.e. no limit in practice.

init_udmabuf() then asks kvmalloc_objs() for pgcnt * sizeof(struct page *)
bytes. __kvmalloc_node_noprof() refuses any request larger than INT_MAX
and splats WARN_ON_ONCE(!(flags & __GFP_NOWARN)) on its way out, while
kvmalloc_objs() defaults to a plain GFP_KERNEL.

A single UDMABUF_CREATE against /dev/udmabuf with a sufficiently large
size is therefore all it takes to trigger:

------------[ cut here ]------------
WARNING: mm/slub.c:7022 at __kvmalloc_node_noprof+0x412/0x5a0
Call Trace:
udmabuf_create+0x11f/0x540
udmabuf_ioctl+0xf1/0x190
__x64_sys_ioctl+0x91/0xe0
do_syscall_64+0xdd/0x4a0

The size is entirely userspace-controlled and allocation failure is
already handled by returning -ENOMEM to the caller, so this is not a
condition the kernel needs to complain about. Pass __GFP_NOWARN and let
the existing error path do its job.

Note that capping the limit instead would change the error reported to
userspace from -ENOMEM to -EINVAL and would reintroduce a fixed ceiling
that the above commit deliberately removed, so __GFP_NOWARN seems the
more faithful fix.

Reported-by: syzbot+bfeed181d1ce9ec87a8f@xxxxxxxxxxxxxxxxxxxxxxxxx
Closes: https://syzkaller.appspot.com/bug?extid=bfeed181d1ce9ec87a8f
Fixes: 44e9eb5a7621 ("dma-buf/udmabuf: Disable the size limit by default")
Signed-off-by: Priyanka Mani <priyankamani2100@xxxxxxxxx>
---
drivers/dma-buf/udmabuf.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index df6dd0046242..127369e502a3 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -190,11 +190,13 @@ static void unpin_all_folios(struct udmabuf *ubuf)

static __always_inline int init_udmabuf(struct udmabuf *ubuf, pgoff_t pgcnt)
{
- ubuf->pages = kvmalloc_objs(*ubuf->pages, pgcnt);
+ ubuf->pages = kvmalloc_objs(*ubuf->pages, pgcnt,
+ GFP_KERNEL | __GFP_NOWARN);
if (!ubuf->pages)
return -ENOMEM;

- ubuf->pinned_folios = kvmalloc_objs(*ubuf->pinned_folios, pgcnt);
+ ubuf->pinned_folios = kvmalloc_objs(*ubuf->pinned_folios, pgcnt,
+ GFP_KERNEL | __GFP_NOWARN);
if (!ubuf->pinned_folios)
return -ENOMEM;

--
2.43.0