Skip to content

Commit fae58d0

Browse files
Ma Kegregkh
authored andcommitted
drm/mediatek: Fix device/node reference count leaks in mtk_drm_get_all_drm_priv
commit 1f40369 upstream. Using device_find_child() and of_find_device_by_node() to locate devices could cause an imbalance in the device's reference count. device_find_child() and of_find_device_by_node() both call get_device() to increment the reference count of the found device before returning the pointer. In mtk_drm_get_all_drm_priv(), these references are never released through put_device(), resulting in permanent reference count increments. Additionally, the for_each_child_of_node() iterator fails to release node references in all code paths. This leaks device node references when loop termination occurs before reaching MAX_CRTC. These reference count leaks may prevent device/node resources from being properly released during driver unbind operations. As comment of device_find_child() says, 'NOTE: you will need to drop the reference with put_device() after use'. Cc: stable@vger.kernel.org Fixes: 1ef7ed4 ("drm/mediatek: Modify mediatek-drm for mt8195 multi mmsys support") Signed-off-by: Ma Ke <make24@iscas.ac.cn> Reviewed-by: CK Hu <ck.hu@mediatek.com> Link: https://patchwork.kernel.org/project/dri-devel/patch/20250812071932.471730-1-make24@iscas.ac.cn/ Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent e15b65e commit fae58d0

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

drivers/gpu/drm/mediatek/mtk_drm_drv.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -388,19 +388,19 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev)
388388

389389
of_id = of_match_node(mtk_drm_of_ids, node);
390390
if (!of_id)
391-
continue;
391+
goto next_put_node;
392392

393393
pdev = of_find_device_by_node(node);
394394
if (!pdev)
395-
continue;
395+
goto next_put_node;
396396

397397
drm_dev = device_find_child(&pdev->dev, NULL, mtk_drm_match);
398398
if (!drm_dev)
399-
continue;
399+
goto next_put_device_pdev_dev;
400400

401401
temp_drm_priv = dev_get_drvdata(drm_dev);
402402
if (!temp_drm_priv)
403-
continue;
403+
goto next_put_device_drm_dev;
404404

405405
if (temp_drm_priv->data->main_len)
406406
all_drm_priv[CRTC_MAIN] = temp_drm_priv;
@@ -412,10 +412,17 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev)
412412
if (temp_drm_priv->mtk_drm_bound)
413413
cnt++;
414414

415-
if (cnt == MAX_CRTC) {
416-
of_node_put(node);
415+
next_put_device_drm_dev:
416+
put_device(drm_dev);
417+
418+
next_put_device_pdev_dev:
419+
put_device(&pdev->dev);
420+
421+
next_put_node:
422+
of_node_put(node);
423+
424+
if (cnt == MAX_CRTC)
417425
break;
418-
}
419426
}
420427

421428
if (drm_priv->data->mmsys_dev_num == cnt) {

0 commit comments

Comments
 (0)