Files
2026-08-24 10:03:24 +08:00

55 lines
2.1 KiB
Diff

Subject: [PATCH] GPUCORE-45392 Fix UAF On User_IO In Queue Bind
This commit fixes a potential use-after-free issue in kbase, where a
queue with a stale uncleaned user-io address still mapped can be
manipulated to permit it binding a second time. This can open up the
potential of yielding use-after-free cases with kbase driver, in
particular with the legacy per-queue memory backed user-io instances.
On the latest per-group backed compact user-io address mapping, the
said issue still triggers a driver kernel warn instance, as the
erroneous rebinding would bear an incorrect reference count.
The fix ensures the queue-binding operation can only succeed if the
user-io address is clean, which means the kbase queue object is
either a fresh one, or any previous mapping had been properly
dismantled with an unmap call on the queue object.
---
diff --git a/product/kernel/drivers/gpu/arm/midgard/csf/mali_kbase_csf.c b/product/kernel/drivers/gpu/arm/midgard/csf/mali_kbase_csf.c
index e4698fb..63dfdb6 100644
--- a/product/kernel/drivers/gpu/arm/midgard/csf/mali_kbase_csf.c
+++ b/product/kernel/drivers/gpu/arm/midgard/csf/mali_kbase_csf.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
*
- * (C) COPYRIGHT 2018-2024 ARM Limited. All rights reserved.
+ * (C) COPYRIGHT 2018-2025 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
@@ -262,6 +262,7 @@
void kbase_csf_free_command_stream_user_pages(struct kbase_context *kctx, struct kbase_queue *queue)
{
kernel_unmap_user_io_pages(kctx, queue);
+ queue->user_io_addr = NULL;
kbase_mem_pool_free_pages(&kctx->mem_pools.small[KBASE_MEM_GROUP_CSF_IO],
KBASEP_NUM_CS_USER_IO_PAGES, queue->phys, true, false);
@@ -718,6 +719,12 @@
if (bind->in.csi_index >= max_streams)
goto out;
+ if (queue->user_io_addr != NULL) {
+ dev_err(kctx->kbdev->dev, "Queue with stale user_io address: %pK",
+ (void *)queue->user_io_addr);
+ goto out;
+ }
+
if (group->run_state == KBASE_CSF_GROUP_TERMINATED)
goto out;