Skip to content

Commit f6c08d3

Browse files
jhovoldgregkh
authored andcommitted
iommu/mediatek: fix use-after-free on probe deferral
commit de83d46 upstream. The driver is dropping the references taken to the larb devices during probe after successful lookup as well as on errors. This can potentially lead to a use-after-free in case a larb device has not yet been bound to its driver so that the iommu driver probe defers. Fix this by keeping the references as expected while the iommu driver is bound. Fixes: 2659392 ("iommu/mediatek: Add error path for loop of mm_dts_parse") Cc: stable@vger.kernel.org Cc: Yong Wu <yong.wu@mediatek.com> Acked-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Johan Hovold <johan@kernel.org> Reviewed-by: Yong Wu <yong.wu@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent bf58ef1 commit f6c08d3

1 file changed

Lines changed: 18 additions & 7 deletions

File tree

drivers/iommu/mtk_iommu.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,24 +1211,28 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m
12111211
}
12121212

12131213
component_match_add(dev, match, component_compare_dev, &plarbdev->dev);
1214-
platform_device_put(plarbdev);
12151214
}
12161215

1217-
if (!frst_avail_smicomm_node)
1218-
return -EINVAL;
1216+
if (!frst_avail_smicomm_node) {
1217+
ret = -EINVAL;
1218+
goto err_larbdev_put;
1219+
}
12191220

12201221
pcommdev = of_find_device_by_node(frst_avail_smicomm_node);
12211222
of_node_put(frst_avail_smicomm_node);
1222-
if (!pcommdev)
1223-
return -ENODEV;
1223+
if (!pcommdev) {
1224+
ret = -ENODEV;
1225+
goto err_larbdev_put;
1226+
}
12241227
data->smicomm_dev = &pcommdev->dev;
12251228

12261229
link = device_link_add(data->smicomm_dev, dev,
12271230
DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
12281231
platform_device_put(pcommdev);
12291232
if (!link) {
12301233
dev_err(dev, "Unable to link %s.\n", dev_name(data->smicomm_dev));
1231-
return -EINVAL;
1234+
ret = -EINVAL;
1235+
goto err_larbdev_put;
12321236
}
12331237
return 0;
12341238

@@ -1400,8 +1404,12 @@ static int mtk_iommu_probe(struct platform_device *pdev)
14001404
iommu_device_sysfs_remove(&data->iommu);
14011405
out_list_del:
14021406
list_del(&data->list);
1403-
if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM))
1407+
if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
14041408
device_link_remove(data->smicomm_dev, dev);
1409+
1410+
for (i = 0; i < MTK_LARB_NR_MAX; i++)
1411+
put_device(data->larb_imu[i].dev);
1412+
}
14051413
out_runtime_disable:
14061414
pm_runtime_disable(dev);
14071415
return ret;
@@ -1421,6 +1429,9 @@ static void mtk_iommu_remove(struct platform_device *pdev)
14211429
if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
14221430
device_link_remove(data->smicomm_dev, &pdev->dev);
14231431
component_master_del(&pdev->dev, &mtk_iommu_com_ops);
1432+
1433+
for (i = 0; i < MTK_LARB_NR_MAX; i++)
1434+
put_device(data->larb_imu[i].dev);
14241435
}
14251436
pm_runtime_disable(&pdev->dev);
14261437
for (i = 0; i < data->plat_data->banks_num; i++) {

0 commit comments

Comments
 (0)