From 9b9abfbc4fc617bfc141049646ad46d655a8ade3 Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Tue, 1 Oct 2024 09:43:47 +0100 Subject: [PATCH] drm/xe/ct: prevent UAF in send_recv() BugLink: https://bugs.launchpad.net/bugs/2097301 commit db7f92af626178ba59dbbcdd5dee9ec24a987a88 upstream. Ensure we serialize with completion side to prevent UAF with fence going out of scope on the stack, since we have no clue if it will fire after the timeout before we can erase from the xa. Also we have some dependent loads and stores for which we need the correct ordering, and we lack the needed barriers. Fix this by grabbing the ct->lock after the wait, which is also held by the completion side. v2 (Badal): - Also print done after acquiring the lock and seeing timeout. Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") Signed-off-by: Matthew Auld Cc: Matthew Brost Cc: Badal Nilawar Cc: # v6.8+ Reviewed-by: Badal Nilawar Link: https://patchwork.freedesktop.org/patch/msgid/20241001084346.98516-5-matthew.auld@intel.com (cherry picked from commit 52789ce35c55ccd30c4b67b9cc5b2af55e0122ea) Signed-off-by: Lucas De Marchi Signed-off-by: Greg Kroah-Hartman CVE-2024-50030 Signed-off-by: Manuel Diewald Signed-off-by: Koichiro Den --- drivers/gpu/drm/xe/xe_guc_ct.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c index 24a33fa36496..2632d4e4e4f4 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.c +++ b/drivers/gpu/drm/xe/xe_guc_ct.c @@ -734,16 +734,26 @@ retry_same_fence: } ret = wait_event_timeout(ct->g2h_fence_wq, g2h_fence.done, HZ); + + /* + * Ensure we serialize with completion side to prevent UAF with fence going out of scope on + * the stack, since we have no clue if it will fire after the timeout before we can erase + * from the xa. Also we have some dependent loads and stores below for which we need the + * correct ordering, and we lack the needed barriers. + */ + mutex_lock(&ct->lock); if (!ret) { - drm_err(&xe->drm, "Timed out wait for G2H, fence %u, action %04x", - g2h_fence.seqno, action[0]); + drm_err(&xe->drm, "Timed out wait for G2H, fence %u, action %04x, done %s", + g2h_fence.seqno, action[0], str_yes_no(g2h_fence.done)); xa_erase_irq(&ct->fence_lookup, g2h_fence.seqno); + mutex_unlock(&ct->lock); return -ETIME; } if (g2h_fence.retry) { drm_warn(&xe->drm, "Send retry, action 0x%04x, reason %d", action[0], g2h_fence.reason); + mutex_unlock(&ct->lock); goto retry; } if (g2h_fence.fail) { @@ -752,6 +762,8 @@ retry_same_fence: ret = -EIO; } + mutex_unlock(&ct->lock); + return ret > 0 ? 0 : ret; }