[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <YIGsJ9LlFquvBI2iWPKhJwjKBwDUr_C-38oVpLJJHJ5rDCY_Zrrv392o6UPNxHoeQrcpLYC9U4fZdpD9ilz6Amg2IxkSexGLQMCQIBek8rc=@protonmail.com>
Date: Thu, 23 Jul 2020 21:10:15 +0000
From: Mazin Rezk <mnrzk@...tonmail.com>
To: "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
"amd-gfx@...ts.freedesktop.org" <amd-gfx@...ts.freedesktop.org>,
"dri-devel@...ts.freedesktop.org" <dri-devel@...ts.freedesktop.org>
Cc: "akpm@...ux-foundation.org" <akpm@...ux-foundation.org>,
"christian.koenig@....com" <christian.koenig@....com>,
"harry.wentland@....com" <harry.wentland@....com>,
"mnrzk@...tonmail.com" <mnrzk@...tonmail.com>,
"nicholas.kazlauskas@....com" <nicholas.kazlauskas@....com>,
"sunpeng.li@....com" <sunpeng.li@....com>,
"keescook@...omium.org" <keescook@...omium.org>,
"alexander.deucher@....com" <alexander.deucher@....com>,
"1i5t5.duncan@....net" <1i5t5.duncan@....net>,
"mphantomx@...oo.com.br" <mphantomx@...oo.com.br>,
"regressions@...mhuis.info" <regressions@...mhuis.info>,
"anthony.ruhier@...il.com" <anthony.ruhier@...il.com>,
"pmenzel@...gen.mpg.de" <pmenzel@...gen.mpg.de>
Subject: [PATCH] amdgpu_dm: fix nonblocking atomic commit use-after-free
When amdgpu_dm_atomic_commit_tail is running in the workqueue,
drm_atomic_state_put will get called while amdgpu_dm_atomic_commit_tail is
running, causing a race condition where state (and then dm_state) is
sometimes freed while amdgpu_dm_atomic_commit_tail is running. This bug has
occurred since 5.7-rc1 and is well documented among polaris11 users [1].
Prior to 5.7, this was not a noticeable issue since the freelist pointer
was stored at the beginning of dm_state (base), which was unused. After
changing the freelist pointer to be stored in the middle of the struct, the
freelist pointer overwrote the context, causing dc_state to become garbage
data and made the call to dm_enable_per_frame_crtc_master_sync dereference
a freelist pointer.
This patch fixes the aforementioned issue by calling drm_atomic_state_get
in amdgpu_dm_atomic_commit before drm_atomic_helper_commit is called and
drm_atomic_state_put after amdgpu_dm_atomic_commit_tail is complete.
According to my testing on 5.8.0-rc6, this should fix bug 207383 on
Bugzilla [1].
[1] https://bugzilla.kernel.org/show_bug.cgi?id=207383
Fixes: 3202fa62f ("slub: relocate freelist pointer to middle of object")
Reported-by: Duncan <1i5t5.duncan@....net>
Signed-off-by: Mazin Rezk <mnrzk@...tonmail.com>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 86ffa0c2880f..86d6652872f2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7303,6 +7303,7 @@ static int amdgpu_dm_atomic_commit(struct drm_device *dev,
* unset legacy_cursor_update
*/
+ drm_atomic_state_get(state);
return drm_atomic_helper_commit(dev, state, nonblock);
/*TODO Handle EINTR, reenable IRQ*/
@@ -7628,6 +7629,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
if (dc_state_temp)
dc_release_state(dc_state_temp);
+
+ drm_atomic_state_put(state);
}
--
2.27.0
Powered by blists - more mailing lists