Memory safety - NULL pointer dereference in CRIU queue restoration path (amdkfd/KFD with Shared MES)

MEDIUM
torvalds/linux
Commit: 8a93f77aec65
Affected: v7.0-rc6 (tracked) and subsequent mainline post-patch; applies to kernels carrying this commit
2026-07-17 16:22 UTC

Description

The commit fixes a memory-safety issue in the AMDGPU KFD CRIU restore path. Specifically, during kfd_criu_restore_queue, the code previously attempted to acquire queue buffers (kfd_queue_acquire_buffers) which could dereference null or invalid pointers if CRIU had not restored buffers or if MES pointers were not prepared. The patch adds a guard in init_user_queue: if MES is enabled and the queue’s wptr_bo is NULL, it logs a message and returns -EINVAL, preventing a potential null pointer dereference. It also removes the unconditional acquire_buffers call from kfd_criu_restore_queue, since acquiring buffers was only needed to prevent a dereference in init_user_queue and is no longer appropriate during CRIU restoration. In short, this is a targeted memory-safety fix to avoid NULL pointer dereferences in CRIU restore flows involving shared MES buffers. It is a real vulnerability fix (memory safety) rather than a pure refactor or test change.

Proof of Concept

PoC (high level, not runnable code): Prerequisites: - A Linux kernel containing this patch (or a vendor/ distro build with AMDKFD CRIU support and Shared MES enabled). - A system with AMDGPU/KFD and CRIU integration enabled. - A user-space workload that creates a KFD queue with Shared MES enabled but does not yet initialize the write pointer buffer (wptr_bo) for that queue. Steps (historical reproduction path for the pre-patch behavior): 1) Start a user-space process that allocates a KFD queue with Shared MES enabled (MES) but delays or omits initializing the queue buffers, so that wptr_bo may be NULL during CRIU restoration. 2) Use CRIU to checkpoint this process after the queue has been created but before buffers are acquired/restored. 3) Restore the process via CRIU, triggering kfd_criu_restore_queue. 4) Observe that, on pre-patch kernels, kfd_criu_restore_queue could race into kfd_queue_acquire_buffers and dereference a NULL or invalid pointer, potentially crashing the kernel. Expected outcome with this patch: - The restore path detects the NULL wptr_bo when MES is enabled and returns -EINVAL instead of dereferencing a NULL pointer, avoiding the crash. - The unconditional kfd_queue_acquire_buffers path is removed from the CRIU restore flow, removing the dereference risk during restoration. Note: This PoC describes a historical vulnerability path. On kernels containing the patch, the described crash should be mitigated by the added guard and the removal of the problematic acquire_buffers call.

Commit Details

Author: David Francis

Date: 2026-06-30 13:58 UTC

Message:

drm/amdkfd: Don't acquire buffers during CRIU queue restore. kfd_criu_restore_queue's call of kfd_queue_acquire_buffers was failing for multiple reasons - The ctl_stack_size set by the CRIU plugin doesn't match what is expected by acquire_buffers - The svm buffer cannot be acquired at this point because CRIU may not have restored it, or may have restored it to a different address. The only reason acquire_buffers was necessary here was to avoid a null ptr dereference in init_user_queue. Just put in a check for that dereference; it doesn't appear to come up in real use cases right now. That is, there is no usage of CRIU with shared MES. This is a partial revert of commit 20a5e7ffdfec ("drm/amdkfd: Properly acquire queue buffers in CRIU restore") Fixes: 20a5e7ffdfec ("drm/amdkfd: Properly acquire queue buffers in CRIU restore") Reviewed-by: David Yat Sin <david.yatsin@amd.com> Signed-off-by: David Francis <David.Francis@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> (cherry picked from commit 1cafa8b29e029eac3ddf64604f891b35dbf6262b) Cc: stable@vger.kernel.org

Triage Assessment

Vulnerability Type: Memory safety - Null pointer dereference

Confidence: MEDIUM

Reasoning:

The patch adds a guard to avoid a null pointer dereference during CRIU queue restoration and removes a risky acquire_buffers path that could dereference null or invalid buffers. This mitigates a memory-safety issue that could lead to crashes or potential exploitation in crash-restoration scenarios. While not a traditional vulnerability like XSS/SQLi, memory safety fixes are relevant to security.

Verification Assessment

Vulnerability Type: Memory safety - NULL pointer dereference in CRIU queue restoration path (amdkfd/KFD with Shared MES)

Confidence: MEDIUM

Affected Versions: v7.0-rc6 (tracked) and subsequent mainline post-patch; applies to kernels carrying this commit

Code Diff

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c index 0ac35789b23994..b8c36907d53650 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c @@ -265,6 +265,11 @@ static int init_user_queue(struct process_queue_manager *pqm, (*q)->process = pqm->process; if (dev->kfd->shared_resources.enable_mes) { + if (!q_properties->wptr_bo) { + pr_debug("Queue initialization with shared MES requires queue buffers to be initialized\n"); + return -EINVAL; + } + retval = amdgpu_amdkfd_alloc_kernel_mem(dev->adev, AMDGPU_MES_GANG_CTX_SIZE, AMDGPU_GEM_DOMAIN_GTT, @@ -1042,18 +1047,10 @@ int kfd_criu_restore_queue(struct kfd_process *p, memset(&qp, 0, sizeof(qp)); set_queue_properties_from_criu(&qp, q_data, NUM_XCC(pdd->dev->adev->gfx.xcc_mask)); - ret = kfd_queue_acquire_buffers(pdd, &qp); - if (ret) { - pr_debug("failed to acquire user queue buffers for CRIU\n"); - goto exit; - } - print_queue_properties(&qp); ret = pqm_create_queue(&p->pqm, pdd->dev, &qp, &queue_id, q_data, mqd, ctl_stack, NULL); if (ret) { - kfd_queue_unref_bo_vas(pdd, &qp); - kfd_queue_release_buffers(pdd, &qp); pr_err("Failed to create new queue err:%d\n", ret); goto exit; }
← Back to Alerts View on GitHub →