]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amdkfd: Validate CRIU-restored IDs before idr_alloc
authorSrinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Thu, 23 Apr 2026 12:59:46 +0000 (18:29 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 28 Apr 2026 18:29:07 +0000 (14:29 -0400)
The KFD CRIU restore flow restores previously saved object IDs from
userspace.

For event restore:

  kfd_criu_restore_event()
      -> create_signal_event() / create_other_event()
          -> allocate_event_notification_slot()
              -> idr_alloc(..., *restore_id, *restore_id + 1, ...)

For BO restore:

  criu_restore_memory_of_gpu()
      -> idr_alloc(..., bo_priv->idr_handle, ...)

In both cases, the restored ID comes from userspace-provided CRIU data.

idr_alloc() expects the ID range values to fit within signed int
limits. If a restored ID is larger than INT_MAX, it can trigger a WARN
in the IDR layer.

A kernel WARN is undesirable because it prints a warning trace and may
cause a panic or reboot on systems with panic_on_warn enabled.

Smatch reported these paths as allowing unchecked userspace values to
reach idr_alloc().

Add INT_MAX validation before using restored IDs in:

- kfd_criu_restore_event()
- criu_restore_memory_of_gpu()

If the restored ID is invalid, return -EINVAL.

This prevents invalid restore data from reaching the IDR layer and
avoids WARN-triggering paths, while keeping valid restore behavior
unchanged.

Fixes: 40e8a766a761 ("drm/amdkfd: CRIU checkpoint and restore events")
Reported-by: Dan Carpenter <error27@gmail.com>
Cc: Felix Kuehling <Felix.Kuehling@amd.com>
Cc: David Yat Sin <david.yatsin@amd.com>
Cc: Rajneesh Bhardwaj <rajneesh.bhardwaj@amd.com>
Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Reviewed-by: David Yat Sin <david.yatsin@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
drivers/gpu/drm/amd/amdkfd/kfd_events.c

index f829d65a79b43e6c50a577dfdd888b12d0e466d0..036c9bcbe58fe891a76c3b17ffb94fa9001ac3a4 100644 (file)
@@ -2340,6 +2340,9 @@ static int criu_restore_memory_of_gpu(struct kfd_process_device *pdd,
        const bool criu_resume = true;
        u64 offset;
 
+       if (bo_priv->idr_handle > INT_MAX)
+               return -EINVAL;
+
        if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL) {
                if (bo_bucket->size !=
                                kfd_doorbell_process_slice(pdd->dev->kfd))
index 44150a71ffd5144e483e10eef49ec9e16276b1a4..a11c4ab3aafd9031eb14c2b45d35256c37826691 100644 (file)
@@ -483,6 +483,11 @@ int kfd_criu_restore_event(struct file *devkfd,
        }
        *priv_data_offset += sizeof(*ev_priv);
 
+       if (ev_priv->event_id > INT_MAX) {
+               ret = -EINVAL;
+               goto exit;
+       }
+
        if (ev_priv->user_handle) {
                ret = kfd_kmap_event_page(p, ev_priv->user_handle);
                if (ret)