* [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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox