[PATCH] drm/i915/guc: Fix ce use-after-free in scrub_guc_desc_for_outstanding_g2h()

Wentao Liang posted 1 patch 1 week, 1 day ago
drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
[PATCH] drm/i915/guc: Fix ce use-after-free in scrub_guc_desc_for_outstanding_g2h()
Posted by Wentao Liang 1 week, 1 day ago
A context flagged SCHED_STATE_DESTROYED has already dropped its final
reference, and __guc_context_destroy() frees it immediately (virtual
engine contexts are kfree'd outright). The pending_disable block is not
mutually exclusive with the destroyed state and kept using the context
after that destroy. Defer __guc_context_destroy() until after the
pending_disable handling.

Fixes: eb5e7da736f3 ("drm/i915/guc: Reset implementation for new GuC interface")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 7b88e081c76d..5eab2baa1f7f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1122,7 +1122,6 @@ static void scrub_guc_desc_for_outstanding_g2h(struct intel_guc *guc)
 			if (destroyed) {
 				intel_gt_pm_put_async_untracked(guc_to_gt(guc));
 				release_guc_id(guc, ce);
-				__guc_context_destroy(ce);
 			}
 			if (pending_enable || deregister)
 				intel_context_put(ce);
@@ -1145,6 +1144,13 @@ static void scrub_guc_desc_for_outstanding_g2h(struct intel_guc *guc)
 			intel_context_put(ce);
 		}
 
+		/*
+		 * Finish the destroy last, as it may free the context while
+		 * the above states still need to access it.
+		 */
+		if (destroyed)
+			__guc_context_destroy(ce);
+
 		if (do_put)
 			intel_context_put(ce);
 		xa_lock(&guc->context_lookup);
-- 
2.34.1