Commit 2de03073 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'exynos-drm-fixes-for-v4.14-rc5' of...

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
parents 33d930e5 238604ca
...@@ -168,11 +168,13 @@ static struct drm_driver exynos_drm_driver = { ...@@ -168,11 +168,13 @@ static struct drm_driver exynos_drm_driver = {
static int exynos_drm_suspend(struct device *dev) static int exynos_drm_suspend(struct device *dev)
{ {
struct drm_device *drm_dev = dev_get_drvdata(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) if (pm_runtime_suspended(dev) || !drm_dev)
return 0; return 0;
private = drm_dev->dev_private;
drm_kms_helper_poll_disable(drm_dev); drm_kms_helper_poll_disable(drm_dev);
exynos_drm_fbdev_suspend(drm_dev); exynos_drm_fbdev_suspend(drm_dev);
private->suspend_state = drm_atomic_helper_suspend(drm_dev); private->suspend_state = drm_atomic_helper_suspend(drm_dev);
...@@ -188,11 +190,12 @@ static int exynos_drm_suspend(struct device *dev) ...@@ -188,11 +190,12 @@ static int exynos_drm_suspend(struct device *dev)
static int exynos_drm_resume(struct device *dev) static int exynos_drm_resume(struct device *dev)
{ {
struct drm_device *drm_dev = dev_get_drvdata(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) if (pm_runtime_suspended(dev) || !drm_dev)
return 0; return 0;
private = drm_dev->dev_private;
drm_atomic_helper_resume(drm_dev, private->suspend_state); drm_atomic_helper_resume(drm_dev, private->suspend_state);
exynos_drm_fbdev_resume(drm_dev); exynos_drm_fbdev_resume(drm_dev);
drm_kms_helper_poll_enable(drm_dev); drm_kms_helper_poll_enable(drm_dev);
...@@ -427,6 +430,7 @@ static void exynos_drm_unbind(struct device *dev) ...@@ -427,6 +430,7 @@ static void exynos_drm_unbind(struct device *dev)
kfree(drm->dev_private); kfree(drm->dev_private);
drm->dev_private = NULL; drm->dev_private = NULL;
dev_set_drvdata(dev, NULL);
drm_dev_unref(drm); drm_dev_unref(drm);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment