Skip to content

Commit f868701

Browse files
srishanmgregkh
authored andcommitted
drm/amdkfd: Validate CRIU-restored IDs before idr_alloc
[ Upstream commit 85043dd ] 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: 40e8a76 ("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> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent cf711d8 commit f868701

2 files changed

Lines changed: 8 additions & 0 deletions

File tree

drivers/gpu/drm/amd/amdkfd/kfd_chardev.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2233,6 +2233,9 @@ static int criu_restore_memory_of_gpu(struct kfd_process_device *pdd,
22332233
const bool criu_resume = true;
22342234
u64 offset;
22352235

2236+
if (bo_priv->idr_handle > INT_MAX)
2237+
return -EINVAL;
2238+
22362239
if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL) {
22372240
if (bo_bucket->size != kfd_doorbell_process_slice(pdd->dev))
22382241
return -EINVAL;

drivers/gpu/drm/amd/amdkfd/kfd_events.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,11 @@ int kfd_criu_restore_event(struct file *devkfd,
478478
}
479479
*priv_data_offset += sizeof(*ev_priv);
480480

481+
if (ev_priv->event_id > INT_MAX) {
482+
ret = -EINVAL;
483+
goto exit;
484+
}
485+
481486
if (ev_priv->user_handle) {
482487
ret = kfd_kmap_event_page(p, ev_priv->user_handle);
483488
if (ret)

0 commit comments

Comments
 (0)