[PATCH] dma-buf/udmabuf: do not warn on huge user-controlled allocations
From: Yuehong Wu
Date: Tue Nov 03 2026 - 07:28:21 EST
Since commit 44e9eb5a7621 ("dma-buf/udmabuf: Disable the size limit by
default") size_limit_mb defaults to INT_MAX, so a user can ask for a
buffer of up to 2 PB. pgcnt is taken from that request and
init_udmabuf() allocates an array of that many pointers before the memfd
is even looked at.
For a request above 1 TB the array is larger than INT_MAX bytes, so
kvmalloc() hits
WARN_ON_ONCE(!(flags & __GFP_NOWARN))
in __kvmalloc_node_noprof(), returns NULL, and udmabuf_create() turns
that into -ENOMEM. The warning is reachable from userspace through
/dev/udmabuf, and with panic_on_warn=1 a bogus ioctl turns into a kernel
panic.
The size is user-controlled and the allocation failure is handled
already, so pass __GFP_NOWARN for the page array, the pinned folio array
and the per-item folio array, matching how other subsystems handle
user-controlled sizes.
Fixes: 44e9eb5a7621 ("dma-buf/udmabuf: Disable the size limit by default")
Signed-off-by: Yuehong Wu <wuyuehong@xxxxxxxxxxxxxxxxxxxx>
---
drivers/dma-buf/udmabuf.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index df6dd00..47e130e 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -190,11 +190,17 @@ 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);
+ /*
+ * pgcnt comes from a user supplied size, so do not warn when
+ * kvmalloc() refuses an impossibly large array.
+ */
+ 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;
@@ -387,7 +393,8 @@ static long udmabuf_create(struct miscdevice *device,
if (ret)
goto err;
- folios = kvmalloc_objs(*folios, max_nr_folios);
+ folios = kvmalloc_objs(*folios, max_nr_folios,
+ GFP_KERNEL | __GFP_NOWARN);
if (!folios) {
ret = -ENOMEM;
goto err;
--
2.43.0