Re: [PATCH RFC v2] drm/lease: use kvmalloc for temporary ioctl arrays
Aleksandr Nogikh <[email protected]>
| Newsgroups | dev.linux.lists.syzbot |
|---|---|
| Message-ID | <CANp29Y7LVN3udb7ZT7VKYxRB9ikLUaX6u6qNzKfbsryn+kzygg@mail.gmail.com> |
#syz upstream On Fri, Jun 19, 2026 at 8:20 AM 'syzbot' via syzkaller-upstream-moderation <[email protected]> wrote: > > In drm_mode_create_lease_ioctl(), a user-controlled object_count is used to > allocate memory for object_ids and objects. If a user provides a very large > object_count, the kernel attempts to allocate a contiguous memory chunk > that exceeds the maximum allowed size by the slab allocator > (KMALLOC_MAX_SIZE). > > For the objects array, kzalloc_objs() is used, which expands to a standard > kzalloc() call. When the requested size exceeds KMALLOC_MAX_SIZE, the SLUB > allocator passes the request to the page allocator, which triggers a > warning because the required page order is greater than MAX_PAGE_ORDER: > > WARNING: mm/page_alloc.c:5197 at __alloc_frozen_pages_noprof+0x2ce/0x380 > mm/page_alloc.c:5197 > Call Trace: > <TASK> > alloc_pages_mpol+0x212/0x380 mm/mempolicy.c:2490 > ___kmalloc_large_node+0x4c/0x120 mm/slub.c:5237 > __kmalloc_large_node_noprof+0x18/0x90 mm/slub.c:5268 > __do_kmalloc_node mm/slub.c:5284 [inline] > __kmalloc_noprof+0x3e4/0x750 mm/slub.c:5308 > kmalloc_noprof include/linux/slab.h:954 [inline] > kzalloc_noprof include/linux/slab.h:1188 [inline] > fill_object_idr drivers/gpu/drm/drm_lease.c:389 [inline] > drm_mode_create_lease_ioctl+0x533/0x1ab0 drivers/gpu/drm/drm_lease.c:521 > > The object_ids and objects arrays are temporary buffers used within the > ioctl to store object IDs and pointers during the lease creation process. > Since these arrays are not used for DMA or hardware access, they do not > require physically contiguous memory. > > To fix this, replace memdup_array_user() with vmemdup_array_user() and > kzalloc_objs() with kvcalloc(), along with changing their respective > kfree() calls to kvfree(). The kvmalloc family of functions attempts a > kmalloc() first and gracefully falls back to vmalloc() for large > allocations. This prevents the kernel warning and makes the allocations > more robust against memory fragmentation, gracefully returning -ENOMEM if > the system cannot satisfy the request. > > Fixes: 62884cd386b8 ("drm: Add four ioctls for managing drm mode object leases [v7]") > Assisted-by: Gemini:gemini-3.1-pro-preview Gemini:gemini-3-flash-preview syzbot > Reported-by: [email protected] > Closes: https://syzkaller.appspot.com/bug?extid=03fb58296859d8dbab4d > Link: https://syzkaller.appspot.com/ai_job?id=22f7a1b3-b0e0-4e5d-abf2-e7119094823a > To: "David Airlie" <[email protected]> > To: <[email protected]> > To: "Maarten Lankhorst" <[email protected]> > To: "Maxime Ripard" <[email protected]> > To: "Simona Vetter" <[email protected]> > To: "Thomas Zimmermann" <[email protected]> > Cc: <[email protected]> > > --- > v2: > - Explicitly stated that the allocated arrays are temporary and do not require physical contiguity as they are not used for DMA or hardware access. > > v1: > https://lore.kernel.org/all/[email protected]/T/ > --- > diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c > index 5d2cf724c..240e0ea6c 100644 > --- a/drivers/gpu/drm/drm_lease.c > +++ b/drivers/gpu/drm/drm_lease.c > @@ -386,7 +386,8 @@ static int fill_object_idr(struct drm_device *dev, > int ret; > bool universal_planes = READ_ONCE(lessor_priv->universal_planes); > > - objects = kzalloc_objs(struct drm_mode_object *, object_count); > + objects = kvcalloc(object_count, sizeof(struct drm_mode_object *), > + GFP_KERNEL); > if (!objects) > return -ENOMEM; > > @@ -462,7 +463,7 @@ static int fill_object_idr(struct drm_device *dev, > if (objects[o]) > drm_mode_object_put(objects[o]); > } > - kfree(objects); > + kvfree(objects); > return ret; > } > > @@ -509,8 +510,8 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev, > /* Handle leased objects, if any */ > idr_init(&leases); > if (object_count != 0) { > - object_ids = memdup_array_user(u64_to_user_ptr(cl->object_ids), > - object_count, sizeof(__u32)); > + object_ids = vmemdup_array_user(u64_to_user_ptr(cl->object_ids), > + object_count, sizeof(__u32)); > if (IS_ERR(object_ids)) { > ret = PTR_ERR(object_ids); > idr_destroy(&leases); > @@ -520,7 +521,7 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev, > /* fill and validate the object idr */ > ret = fill_object_idr(dev, lessor_priv, &leases, > object_count, object_ids); > - kfree(object_ids); > + kvfree(object_ids); > if (ret) { > drm_dbg_lease(dev, "lease object lookup failed: %i\n", ret); > idr_destroy(&leases); > > > base-commit: 8cd9520d35a6c38db6567e97dd93b1f11f185dc6 > -- > This is an AI-generated patch subject to moderation. > Reply with '#syz upstream' to Sign-off the patch as a human author > and send it to the upstream kernel mailing lists. > Reply with '#syz reject' to reject it ('#syz unreject' to undo). > > See https://goo.gle/syzbot-ai-patches for information about AI-generated patches. > You can comment on the patch as usual, syzbot will try to address > the comments and send a new version of the patch if necessary. > syzbot engineers can be reached at [email protected]. > > -- > You received this message because you are subscribed to the Google Groups "syzkaller-upstream-moderation" group. > To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. > To view this discussion visit https://groups.google.com/d/msgid/syzkaller-upstream-moderation/3c78114e-ed6d-4b15-9d77-4f8ddd7f9cd8%40mail.kernel.org.