The vdec driver retrieves a canvas instance using meson_canvas_get() and stores the raw pointer in core->canvas. However, the helper drops the provider device reference via put_device() right before returning. Because no formal device relationship is established, an unbind of the canvas provider driver triggers a Use-After-Free (UAF) bug when the video decoder subsequently attempts to access that memory block.
Fix this lifecycle hazard by enhancing meson_canvas_get() to establish a formal managed device link between the consumer device and the underlying canvas platform device. Using DL_FLAG_AUTOREMOVE_CONSUMER ensures the dependency link is automatically torn down when the consumer driver unbinds. Additionally, handle missing link conditions using dev_err_probe() to clean up upstream error diagnostics, and ensure the canvas platform device reference count is dropped safely along the uninitialized driver data path. Cc: Nicolas Dufresne <[email protected]> Reported-by: Sashiko <[email protected]> Closes: https://lore.kernel.org/all/[email protected] Signed-off-by: Anand Moon <[email protected]> --- drivers/soc/amlogic/meson-canvas.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/soc/amlogic/meson-canvas.c b/drivers/soc/amlogic/meson-canvas.c index 79681afea8c61..5102a491bf778 100644 --- a/drivers/soc/amlogic/meson-canvas.c +++ b/drivers/soc/amlogic/meson-canvas.c @@ -54,6 +54,7 @@ struct meson_canvas *meson_canvas_get(struct device *dev) struct device_node *canvas_node; struct platform_device *canvas_pdev; struct meson_canvas *canvas; + struct device_link *link; canvas_node = of_parse_phandle(dev->of_node, "amlogic,canvas", 0); if (!canvas_node) @@ -70,9 +71,18 @@ struct meson_canvas *meson_canvas_get(struct device *dev) * current state, this driver probe cannot return -EPROBE_DEFER */ canvas = dev_get_drvdata(&canvas_pdev->dev); - put_device(&canvas_pdev->dev); - if (!canvas) + if (!canvas) { + put_device(&canvas_pdev->dev); return ERR_PTR(-EINVAL); + } + + /* Establish device link to prevent Use-After-Free */ + link = device_link_add(dev, &canvas_pdev->dev, + DL_FLAG_AUTOREMOVE_CONSUMER); + put_device(&canvas_pdev->dev); + if (!link) + return ERR_PTR(dev_err_probe(dev, -EINVAL, + "Failed to create device link canvas\n")); return canvas; } -- 2.50.1
