summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-10-17 10:14:56 +1000
committerDave Airlie <airlied@redhat.com>2017-10-17 10:14:56 +1000
commit2de0307323fc42c6395d0eafec9879d55e042c85 (patch)
tree1011092a543740582dab2b2444a6aaf40b09b78e
parent33d930e59a98fa10a0db9f56c7fa2f21a4aef9b9 (diff)
parent238604ca0b708319e089e22545bcda39afb5faa8 (diff)
downloadlinux-2de0307323fc42c6395d0eafec9879d55e042c85.tar.bz2
Merge tag 'exynos-drm-fixes-for-v4.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-fixes
- Fix potential use-after-free issue in suspend/resume by cleanning up drvdata at unbind. - Fix potential NULL pointer dereference issue in suspend/resume by setting drm_dev after checking if drm_dev is null or not. * tag 'exynos-drm-fixes-for-v4.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: drm/exynos: Clear drvdata after component unbind drm/exynos: Fix potential NULL pointer dereference in suspend/resume paths
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index e651a58c18cf..82b72425a42f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -168,11 +168,13 @@ static struct drm_driver exynos_drm_driver = {
static int exynos_drm_suspend(struct device *dev)
{
struct drm_device *drm_dev = dev_get_drvdata(dev);
- struct exynos_drm_private *private = drm_dev->dev_private;
+ struct exynos_drm_private *private;
if (pm_runtime_suspended(dev) || !drm_dev)
return 0;
+ private = drm_dev->dev_private;
+
drm_kms_helper_poll_disable(drm_dev);
exynos_drm_fbdev_suspend(drm_dev);
private->suspend_state = drm_atomic_helper_suspend(drm_dev);
@@ -188,11 +190,12 @@ static int exynos_drm_suspend(struct device *dev)
static int exynos_drm_resume(struct device *dev)
{
struct drm_device *drm_dev = dev_get_drvdata(dev);
- struct exynos_drm_private *private = drm_dev->dev_private;
+ struct exynos_drm_private *private;
if (pm_runtime_suspended(dev) || !drm_dev)
return 0;
+ private = drm_dev->dev_private;
drm_atomic_helper_resume(drm_dev, private->suspend_state);
exynos_drm_fbdev_resume(drm_dev);
drm_kms_helper_poll_enable(drm_dev);
@@ -427,6 +430,7 @@ static void exynos_drm_unbind(struct device *dev)
kfree(drm->dev_private);
drm->dev_private = NULL;
+ dev_set_drvdata(dev, NULL);
drm_dev_unref(drm);
}