From: Tuo Li islituo@gmail.com
stable inclusion from stable-v6.6-rc1 commit 2e63972a2de14482d0eae1a03a73e379f1c3f44c category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I917IV CVE: CVE-2024-22386
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
---------------------------
The variable crtc->state->event is often protected by the lock crtc->dev->event_lock when is accessed. However, it is accessed as a condition of an if statement in exynos_drm_crtc_atomic_disable() without holding the lock:
if (crtc->state->event && !crtc->state->active)
However, if crtc->state->event is changed to NULL by another thread right after the conditions of the if statement is checked to be true, a null-pointer dereference can occur in drm_crtc_send_vblank_event():
e->pipe = pipe;
To fix this possible null-pointer dereference caused by data race, the spin lock coverage is extended to protect the if statement as well as the function call to drm_crtc_send_vblank_event().
Reported-by: BassCheck bass@buaa.edu.cn Link: https://sites.google.com/view/basscheck/home Signed-off-by: Tuo Li islituo@gmail.com Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Added relevant link. Signed-off-by: Inki Dae inki.dae@samsung.com Signed-off-by: Hui Tang tanghui20@huawei.com --- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 2696289ecc78..b3e23ace5869 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -43,13 +43,12 @@ static void exynos_drm_crtc_atomic_disable(struct drm_crtc *crtc, if (exynos_crtc->ops->disable) exynos_crtc->ops->disable(exynos_crtc);
+ spin_lock_irq(&crtc->dev->event_lock); if (crtc->state->event && !crtc->state->active) { - spin_lock_irq(&crtc->dev->event_lock); drm_crtc_send_vblank_event(crtc, crtc->state->event); - spin_unlock_irq(&crtc->dev->event_lock); - crtc->state->event = NULL; } + spin_unlock_irq(&crtc->dev->event_lock); }
static int exynos_crtc_atomic_check(struct drm_crtc *crtc,