On 1/23/26 15:15, Tvrtko Ursulin wrote:
> 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 <[email protected]>
> Reported-by: Zhi Wang <[email protected]>
> Fixes: 53096728b891 ("drm: Add DRM prime interface to reassign GEM handle")
> Cc: David Francis <[email protected]>
> Cc: Felix Kuehling <[email protected]>
> Cc: Christian König <[email protected]>
> Cc: <[email protected]> # v6.18+

Reviewed-by: Christian König <[email protected]>

> ---
> v2:
>  * Rename local variable, re-position comment, drop the else block. 
> (Christian)
>  * Use local at more places.
> ---
>  drivers/gpu/drm/drm_gem.c | 18 ++++++++++++------
>  1 file changed, 12 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> index 7ff6b7bbeb73..ffa7852c8f6c 100644
> --- a/drivers/gpu/drm/drm_gem.c
> +++ b/drivers/gpu/drm/drm_gem.c
> @@ -1001,16 +1001,21 @@ int drm_gem_change_handle_ioctl(struct drm_device 
> *dev, void *data,
>  {
>       struct drm_gem_change_handle *args = data;
>       struct drm_gem_object *obj;
> -     int ret;
> +     int handle, ret;
>  
>       if (!drm_core_check_feature(dev, DRIVER_GEM))
>               return -EOPNOTSUPP;
>  
> +     /* idr_alloc() limitation. */
> +     if (args->new_handle > INT_MAX)
> +             return -EINVAL;
> +     handle = args->new_handle;
> +
>       obj = drm_gem_object_lookup(file_priv, args->handle);
>       if (!obj)
>               return -ENOENT;
>  
> -     if (args->handle == args->new_handle) {
> +     if (args->handle == handle) {
>               ret = 0;
>               goto out;
>       }
> @@ -1018,18 +1023,19 @@ int drm_gem_change_handle_ioctl(struct drm_device 
> *dev, void *data,
>       mutex_lock(&file_priv->prime.lock);
>  
>       spin_lock(&file_priv->table_lock);
> -     ret = idr_alloc(&file_priv->object_idr, obj,
> -             args->new_handle, args->new_handle + 1, GFP_NOWAIT);
> +     ret = idr_alloc(&file_priv->object_idr, obj, handle, handle + 1,
> +                     GFP_NOWAIT);
>       spin_unlock(&file_priv->table_lock);
>  
>       if (ret < 0)
>               goto out_unlock;
>  
>       if (obj->dma_buf) {
> -             ret = drm_prime_add_buf_handle(&file_priv->prime, obj->dma_buf, 
> args->new_handle);
> +             ret = drm_prime_add_buf_handle(&file_priv->prime, obj->dma_buf,
> +                                            handle);
>               if (ret < 0) {
>                       spin_lock(&file_priv->table_lock);
> -                     idr_remove(&file_priv->object_idr, args->new_handle);
> +                     idr_remove(&file_priv->object_idr, handle);
>                       spin_unlock(&file_priv->table_lock);
>                       goto out_unlock;
>               }

Reply via email to