> -----Original Message----- > From: Tuo Li <islituo@xxxxxxxxx> > Sent: Friday, June 30, 2023 11:19 AM > To: inki.dae@xxxxxxxxxxx; sw0312.kim@xxxxxxxxxxx; > kyungmin.park@xxxxxxxxxxx; airlied@xxxxxxxxx; daniel@xxxxxxxx; > krzysztof.kozlowski@xxxxxxxxxx; alim.akhtar@xxxxxxxxxxx > Cc: dri-devel@xxxxxxxxxxxxxxxxxxxxx; linux-arm-kernel@xxxxxxxxxxxxxxxxxxx; > linux-samsung-soc@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; > baijiaju1990@xxxxxxxxxxx; Tuo Li <islituo@xxxxxxxxx>; BassCheck > <bass@xxxxxxxxxxx> > 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 <bass@xxxxxxxxxxx> > Signed-off-by: Tuo Li <islituo@xxxxxxxxx> 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