Skip to content

Commit 12f15d5

Browse files
Tvrtko Ursulintursulin
authored andcommitted
drm: Do not allow userspace to trigger kernel warnings in drm_gem_change_handle_ioctl()
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
1 parent 0a095b6 commit 12f15d5

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
@@ -960,35 +960,41 @@ int drm_gem_change_handle_ioctl(struct drm_device *dev, void *data,
960960
{
961961
struct drm_gem_change_handle *args = data;
962962
struct drm_gem_object *obj;
963-
int ret;
963+
int handle, ret;
964964

965965
if (!drm_core_check_feature(dev, DRIVER_GEM))
966966
return -EOPNOTSUPP;
967967

968+
/* idr_alloc() limitation. */
969+
if (args->new_handle > INT_MAX)
970+
return -EINVAL;
971+
handle = args->new_handle;
972+
968973
obj = drm_gem_object_lookup(file_priv, args->handle);
969974
if (!obj)
970975
return -ENOENT;
971976

972-
if (args->handle == args->new_handle) {
977+
if (args->handle == handle) {
973978
ret = 0;
974979
goto out;
975980
}
976981

977982
mutex_lock(&file_priv->prime.lock);
978983

979984
spin_lock(&file_priv->table_lock);
980-
ret = idr_alloc(&file_priv->object_idr, obj,
981-
args->new_handle, args->new_handle + 1, GFP_NOWAIT);
985+
ret = idr_alloc(&file_priv->object_idr, obj, handle, handle + 1,
986+
GFP_NOWAIT);
982987
spin_unlock(&file_priv->table_lock);
983988

984989
if (ret < 0)
985990
goto out_unlock;
986991

987992
if (obj->dma_buf) {
988-
ret = drm_prime_add_buf_handle(&file_priv->prime, obj->dma_buf, args->new_handle);
993+
ret = drm_prime_add_buf_handle(&file_priv->prime, obj->dma_buf,
994+
handle);
989995
if (ret < 0) {
990996
spin_lock(&file_priv->table_lock);
991-
idr_remove(&file_priv->object_idr, args->new_handle);
997+
idr_remove(&file_priv->object_idr, handle);
992998
spin_unlock(&file_priv->table_lock);
993999
goto out_unlock;
9941000
}

0 commit comments

Comments
 (0)