[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20250131124421.152497-1-r.smirnov@omp.ru>
Date: Fri, 31 Jan 2025 15:44:17 +0300
From: Roman Smirnov <r.smirnov@....ru>
To: Maarten Lankhorst <maarten.lankhorst@...ux.intel.com>, Maxime Ripard
<mripard@...nel.org>, Thomas Zimmermann <tzimmermann@...e.de>, David Airlie
<airlied@...il.com>, Simona Vetter <simona@...ll.ch>
CC: Roman Smirnov <r.smirnov@....ru>, Dave Airlie <airlied@...hat.com>, Keith
Packard <keithp@...thp.com>, <dri-devel@...ts.freedesktop.org>,
<linux-kernel@...r.kernel.org>, <lvc-project@...uxtesting.org>, syzbot
<syzbot+6754751ad05524dae739@...kaller.appspotmail.com>
Subject: [PATCH] drm/drm_lease: add sanity check to drm_mode_create_lease_ioctl()
Syzkaller found a case of dangerous call via drm_ioctl(). If user makes
object_count too large, WARN() is called when allocating memory:
------------[ cut here ]------------
WARNING: CPU: 0 PID: 5229 at mm/page_alloc.c:4709 __alloc_pages_noprof+0x3bd/0x710 mm/page_alloc.c:4709
Modules linked in:
CPU: 0 UID: 0 PID: 5229 Comm: syz-executor478 Not tainted 6.12.0-rc4-syzkaller-00047-gc2ee9f594da8 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
Call Trace:
<TASK>
__alloc_pages_node_noprof include/linux/gfp.h:269 [inline]
alloc_pages_node_noprof include/linux/gfp.h:296 [inline]
___kmalloc_large_node+0x8b/0x1d0 mm/slub.c:4209
__kmalloc_large_node_noprof+0x1a/0x80 mm/slub.c:4236
__do_kmalloc_node mm/slub.c:4252 [inline]
__kmalloc_noprof+0x2ae/0x400 mm/slub.c:4276
kmalloc_noprof include/linux/slab.h:882 [inline]
kmalloc_array_noprof include/linux/slab.h:923 [inline]
fill_object_idr drivers/gpu/drm/drm_lease.c:389 [inline]
drm_mode_create_lease_ioctl+0x580/0x1db0 drivers/gpu/drm/drm_lease.c:522
drm_ioctl_kernel+0x337/0x440 drivers/gpu/drm/drm_ioctl.c:745
drm_ioctl+0x60e/0xad0 drivers/gpu/drm/drm_ioctl.c:842
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:907 [inline]
__se_sys_ioctl+0xf9/0x170 fs/ioctl.c:893
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
</TASK>
The number of objects requested for lessee must not exceed the
number of objects already in lessor because if the user requests
more identifiers than lessor has, one of the calls of idr_find()
in drm_lease_create() will return NULL. Then ioctl() will
terminate with an error.
The added check handles this case before calling kcalloc(),
which prevents WARN() from being called.
Reported-by: syzbot <syzbot+6754751ad05524dae739@...kaller.appspotmail.com>
Closes: https://syzkaller.appspot.com/bug?extid=6754751ad05524dae739
Fixes: 62884cd386b8 ("drm: Add four ioctls for managing drm mode object leases [v7]")
Signed-off-by: Roman Smirnov <r.smirnov@....ru>
---
drivers/gpu/drm/drm_lease.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
index 94375c6a5425..c1bebc70e544 100644
--- a/drivers/gpu/drm/drm_lease.c
+++ b/drivers/gpu/drm/drm_lease.c
@@ -336,6 +336,23 @@ static void _drm_lease_revoke(struct drm_master *top)
}
}
+static int validate_object_count(struct drm_device *dev,
+ size_t object_count)
+{
+ size_t available_objects = 0;
+ int object;
+ void *entry;
+
+ mutex_lock(&dev->mode_config.idr_mutex);
+ idr_for_each_entry(&dev->mode_config.object_idr, entry, object)
+ available_objects++;
+ mutex_unlock(&dev->mode_config.idr_mutex);
+
+ if (available_objects < object_count)
+ return -EINVAL;
+ return 0;
+}
+
void drm_lease_revoke(struct drm_master *top)
{
mutex_lock(&top->dev->mode_config.idr_mutex);
@@ -507,6 +524,12 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev,
object_count = cl->object_count;
+ ret = validate_object_count(lessor->dev, object_count);
+ if (ret) {
+ drm_dbg_lease(dev, "requested too many objects\n");
+ goto out_lessor;
+ }
+
/* Handle leased objects, if any */
idr_init(&leases);
if (object_count != 0) {
--
2.43.0
Powered by blists - more mailing lists