[PATCH v7 17/19] media: meson: canvas: Fix Use-After-Free by linking canvas provider device

From: Anand Moon

Date: Mon Jul 13 2026 - 08:20:04 EST


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 <nicolas@xxxxxxxxxxxx>
Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
Closes: https://lore.kernel.org/all/20260530111022.9C6D71F00893@xxxxxxxxxxxxxxx
Signed-off-by: Anand Moon <linux.amoon@xxxxxxxxx>
---
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