> -----Original Message----- > From: Tuo Li <isli...@gmail.com> > Sent: Friday, June 30, 2023 11:19 AM > To: inki....@samsung.com; sw0312....@samsung.com; > kyungmin.p...@samsung.com; airl...@gmail.com; dan...@ffwll.ch; > krzysztof.kozlow...@linaro.org; alim.akh...@samsung.com > Cc: dri-devel@lists.freedesktop.org; linux-arm-ker...@lists.infradead.org; > linux-samsung-...@vger.kernel.org; linux-ker...@vger.kernel.org; > baijiaju1...@outlook.com; Tuo Li <isli...@gmail.com>; BassCheck > <b...@buaa.edu.cn> > Subject: [PATCH] drm/exynos: fix a possible null-pointer dereference due > to data race in exynos_drm_crtc_atomic_disable() > > 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 <b...@buaa.edu.cn> > Signed-off-by: Tuo Li <isli...@gmail.com> Applied. Thanks, Inki Dae > --- > 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 4153f302de7c..d19e796c2061 100644 > --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c > +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c > @@ -39,13 +39,12 @@ static void exynos_drm_crtc_atomic_disable(struct > drm_crtc *crtc, > if (exynos_crtc->ops->atomic_disable) > exynos_crtc->ops->atomic_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, > -- > 2.34.1