All of lore.kernel.org
 help / color / mirror / Atom feed
* [bug report] drm/amdkfd: CRIU checkpoint and restore events
@ 2026-04-23  6:13 Dan Carpenter
  0 siblings, 0 replies; only message in thread
From: Dan Carpenter @ 2026-04-23  6:13 UTC (permalink / raw)
  To: David Yat Sin; +Cc: amd-gfx, SHANMUGAM, SRINIVASAN

Hello David Yat Sin,

Commit 40e8a766a761 ("drm/amdkfd: CRIU checkpoint and restore
events") from Mar 5, 2021 (linux-next), leads to the following Smatch
static checker warning:

drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_events.c:110 allocate_event_notification_slot() warn: idr_alloc start value from user can be < 0

[ There are a couple older warnings as well ]

drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_events.c:226 create_other_event() warn: idr_alloc start value from user can be < 0
drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_chardev.c:2367 criu_restore_memory_of_gpu() warn: idr_alloc start value from user can be < 0

drivers/gpu/drm/amd/amdkfd/kfd_events.c
   454  int kfd_criu_restore_event(struct file *devkfd,
   455                             struct kfd_process *p,
   456                             uint8_t __user *user_priv_ptr,
   457                             uint64_t *priv_data_offset,
   458                             uint64_t max_priv_data_size)
   459  {
   460          struct kfd_criu_event_priv_data *ev_priv;
   461          struct kfd_event *ev = NULL;
   462          int ret = 0;
   463  
   464          ev_priv = kmalloc_obj(*ev_priv);
   465          if (!ev_priv)
   466                  return -ENOMEM;
   467  
   468          ev = kzalloc_obj(*ev);
   469          if (!ev) {
   470                  ret = -ENOMEM;
   471                  goto exit;
   472          }
   473  
   474          if (*priv_data_offset + sizeof(*ev_priv) > max_priv_data_size) {
   475                  ret = -EINVAL;
   476                  goto exit;
   477          }
   478  
   479          ret = copy_from_user(ev_priv, user_priv_ptr + *priv_data_offset, sizeof(*ev_priv));
   480          if (ret) {
   481                  ret = -EFAULT;
   482                  goto exit;
   483          }
   484          *priv_data_offset += sizeof(*ev_priv);
   485  
   486          if (ev_priv->user_handle) {
   487                  ret = kfd_kmap_event_page(p, ev_priv->user_handle);
   488                  if (ret)
   489                          goto exit;
   490          }
   491  
   492          ev->type = ev_priv->type;
   493          ev->auto_reset = ev_priv->auto_reset;
   494          ev->signaled = ev_priv->signaled;
   495  
   496          spin_lock_init(&ev->lock);
   497          init_waitqueue_head(&ev->wq);
   498  
   499          mutex_lock(&p->event_mutex);
   500          switch (ev->type) {
   501          case KFD_EVENT_TYPE_SIGNAL:
   502          case KFD_EVENT_TYPE_DEBUG:
   503                  ret = create_signal_event(devkfd, p, ev, &ev_priv->event_id);
                                                                  ^^^^^^^^^^^^^^^^^
If this is more than INT_MAX then it triggers a WARN() at the start of
idr_alloc().  Greg KH always points out that technically most linux users
have reboot on WARN() enabled so this is a quite bad bug.

   504                  break;

The other warnings come from;
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
   841  static int kfd_ioctl_create_event(struct file *filp, struct kfd_process *p,
   842                                          void *data)
   843  {
   844          struct kfd_ioctl_create_event_args *args = data;
   845          int err;
   846  
   847          /* For dGPUs the event page is allocated in user mode. The
   848           * handle is passed to KFD with the first call to this IOCTL
   849           * through the event_page_offset field.
   850           */
   851          if (args->event_page_offset) {
   852                  mutex_lock(&p->mutex);
   853                  err = kfd_kmap_event_page(p, args->event_page_offset);
   854                  mutex_unlock(&p->mutex);
   855                  if (err)
   856                          return err;
   857          }
   858  
   859          err = kfd_event_create(filp, p, args->event_type,
   860                                  args->auto_reset != 0, args->node_id,
   861                                  &args->event_id, &args->event_trigger_data,
                                        ^^^^^^^^^^^^^^^
Not checked.

   862                                  &args->event_page_offset,
   863                                  &args->event_slot_index);
   864  
   865          pr_debug("Created event (id:0x%08x) (%s)\n", args->event_id, __func__);
   866          return err;
   867  }

drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
  2456  static int criu_restore_bos(struct kfd_process *p,
  2457                              struct kfd_ioctl_criu_args *args,
  2458                              uint64_t *priv_offset,
  2459                              uint64_t max_priv_data_size)
  2460  {
  2461          struct kfd_criu_bo_bucket *bo_buckets = NULL;
  2462          struct kfd_criu_bo_priv_data *bo_privs = NULL;
  2463          struct file **files = NULL;
  2464          int ret = 0;
  2465          uint32_t i = 0;
  2466  
  2467          if (*priv_offset + (args->num_bos * sizeof(*bo_privs)) > max_priv_data_size)
  2468                  return -EINVAL;
  2469  
  2470          /* Prevent MMU notifications until stage-4 IOCTL (CRIU_RESUME) is received */
  2471          amdgpu_amdkfd_block_mmu_notifications(p->kgd_process_info);
  2472  
  2473          bo_buckets = kvmalloc_objs(*bo_buckets, args->num_bos);
  2474          if (!bo_buckets)
  2475                  return -ENOMEM;
  2476  
  2477          files = kvzalloc(args->num_bos * sizeof(struct file *), GFP_KERNEL);
  2478          if (!files) {
  2479                  ret = -ENOMEM;
  2480                  goto exit;
  2481          }
  2482  
  2483          ret = copy_from_user(bo_buckets, (void __user *)args->bos,
  2484                               args->num_bos * sizeof(*bo_buckets));
  2485          if (ret) {
  2486                  pr_err("Failed to copy BOs information from user\n");
  2487                  ret = -EFAULT;
  2488                  goto exit;
  2489          }
  2490  
  2491          bo_privs = kvmalloc_objs(*bo_privs, args->num_bos);
  2492          if (!bo_privs) {
  2493                  ret = -ENOMEM;
  2494                  goto exit;
  2495          }
  2496  
  2497          ret = copy_from_user(bo_privs, (void __user *)args->priv_data + *priv_offset,
  2498                               args->num_bos * sizeof(*bo_privs));
  2499          if (ret) {
  2500                  pr_err("Failed to copy BOs information from user\n");
  2501                  ret = -EFAULT;
  2502                  goto exit;
  2503          }
  2504          *priv_offset += args->num_bos * sizeof(*bo_privs);
  2505  
  2506          /* Create and map new BOs */
  2507          for (; i < args->num_bos; i++) {
  2508                  ret = criu_restore_bo(p, &bo_buckets[i], &bo_privs[i], &files[i]);
                                                                 ^^^^^^^^^^^^
Unchecked event_ids.

  2509                  if (ret) {
  2510                          pr_debug("Failed to restore BO[%d] ret%d\n", i, ret);
  2511                          goto exit;
  2512                  }
  2513          } /* done */


This email is a free service from the Smatch-CI project [smatch.sf.net].

regards,
dan carpenter

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-04-23  8:52 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-23  6:13 [bug report] drm/amdkfd: CRIU checkpoint and restore events Dan Carpenter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.