Skip to content

Commit ae8831e

Browse files
Tvrtko Ursulingregkh
authored andcommitted
drm: Do not allow userspace to trigger kernel warnings in drm_gem_change_handle_ioctl()
commit 12f15d5 upstream. Since GEM bo handles are u32 in the uapi and the internal implementation uses idr_alloc() which uses int ranges, passing a new handle larger than INT_MAX trivially triggers a kernel warning: idr_alloc(): ... if (WARN_ON_ONCE(start < 0)) return -EINVAL; ... Fix it by rejecting new handles above INT_MAX and at the same time make the end limit calculation more obvious by moving into int domain. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Reported-by: Zhi Wang <wangzhi@stu.xidian.edu.cn> Fixes: 5309672 ("drm: Add DRM prime interface to reassign GEM handle") Cc: David Francis <David.Francis@amd.com> Cc: Felix Kuehling <felix.kuehling@amd.com> Cc: Christian König <christian.koenig@amd.com> Cc: <stable@vger.kernel.org> # v6.18+ Tested-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com> Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net> Link: https://lore.kernel.org/r/20260123141540.76540-1-tvrtko.ursulin@igalia.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent dd222df commit ae8831e

1 file changed

Lines changed: 12 additions & 6 deletions

File tree

drivers/gpu/drm/drm_gem.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -970,35 +970,41 @@ int drm_gem_change_handle_ioctl(struct drm_device *dev, void *data,
970970
{
971971
struct drm_gem_change_handle *args = data;
972972
struct drm_gem_object *obj;
973-
int ret;
973+
int handle, ret;
974974

975975
if (!drm_core_check_feature(dev, DRIVER_GEM))
976976
return -EOPNOTSUPP;
977977

978+
/* idr_alloc() limitation. */
979+
if (args->new_handle > INT_MAX)
980+
return -EINVAL;
981+
handle = args->new_handle;
982+
978983
obj = drm_gem_object_lookup(file_priv, args->handle);
979984
if (!obj)
980985
return -ENOENT;
981986

982-
if (args->handle == args->new_handle) {
987+
if (args->handle == handle) {
983988
ret = 0;
984989
goto out;
985990
}
986991

987992
mutex_lock(&file_priv->prime.lock);
988993

989994
spin_lock(&file_priv->table_lock);
990-
ret = idr_alloc(&file_priv->object_idr, obj,
991-
args->new_handle, args->new_handle + 1, GFP_NOWAIT);
995+
ret = idr_alloc(&file_priv->object_idr, obj, handle, handle + 1,
996+
GFP_NOWAIT);
992997
spin_unlock(&file_priv->table_lock);
993998

994999
if (ret < 0)
9951000
goto out_unlock;
9961001

9971002
if (obj->dma_buf) {
998-
ret = drm_prime_add_buf_handle(&file_priv->prime, obj->dma_buf, args->new_handle);
1003+
ret = drm_prime_add_buf_handle(&file_priv->prime, obj->dma_buf,
1004+
handle);
9991005
if (ret < 0) {
10001006
spin_lock(&file_priv->table_lock);
1001-
idr_remove(&file_priv->object_idr, args->new_handle);
1007+
idr_remove(&file_priv->object_idr, handle);
10021008
spin_unlock(&file_priv->table_lock);
10031009
goto out_unlock;
10041010
}

0 commit comments

Comments
 (0)