summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/imx/parallel-display.c
diff options
context:
space:
mode:
authorPhilipp Zabel <p.zabel@pengutronix.de>2020-06-11 14:43:31 +0200
committerPhilipp Zabel <p.zabel@pengutronix.de>2020-07-20 15:15:59 +0200
commitba807c94f67fd64b3051199810d9e4dd209fdc00 (patch)
tree361e29ea050356316aafd040e07e3938ade8e7f9 /drivers/gpu/drm/imx/parallel-display.c
parentb3a9e3b9622ae10064826dccb4f7a52bd88c7407 (diff)
drm/imx: fix use after free
Component driver structures allocated with devm_kmalloc() in bind() are freed automatically after unbind(). Since the contained drm structures are accessed afterwards in drm_mode_config_cleanup(), move the allocation into probe() to extend the driver structure's lifetime to the lifetime of the device. This should eventually be changed to use drm resource managed allocations with lifetime of the drm device. We also need to ensure that all componets are available during the unbind() so we need to call component_unbind_all() before we free non-devres resources like planes. Note this patch fixes the the use after free bug but introduces a possible boot loop issue. The issue is triggered if the HDMI support is enabled and a component driver always return -EPROBE_DEFER, see discussion [1] for more details. [1] https://lkml.org/lkml/2020/3/24/1467 Fixes: 17b5001b5143 ("imx-drm: convert to componentised device support") Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> [m.felsch@pengutronix: fix imx_tve_probe()] [m.felsch@pengutronix: resort component_unbind_all()) [m.felsch@pengutronix: adapt commit message] Signed-off-by: Marco Felsch <m.felsch@pengutronix.de> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Diffstat (limited to 'drivers/gpu/drm/imx/parallel-display.c')
-rw-r--r--drivers/gpu/drm/imx/parallel-display.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
index ac916c84a631..622eabe9efb3 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -326,9 +326,8 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
u32 bus_format = 0;
const char *fmt;
- imxpd = devm_kzalloc(dev, sizeof(*imxpd), GFP_KERNEL);
- if (!imxpd)
- return -ENOMEM;
+ imxpd = dev_get_drvdata(dev);
+ memset(imxpd, 0, sizeof(*imxpd));
edidp = of_get_property(np, "edid", &imxpd->edid_len);
if (edidp)
@@ -359,8 +358,6 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
if (ret)
return ret;
- dev_set_drvdata(dev, imxpd);
-
return 0;
}
@@ -382,6 +379,14 @@ static const struct component_ops imx_pd_ops = {
static int imx_pd_probe(struct platform_device *pdev)
{
+ struct imx_parallel_display *imxpd;
+
+ imxpd = devm_kzalloc(&pdev->dev, sizeof(*imxpd), GFP_KERNEL);
+ if (!imxpd)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, imxpd);
+
return component_add(&pdev->dev, &imx_pd_ops);
}