Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iommu/mediatek: fix use-after-free on probe deferral

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: 26593928564c ("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>

authored by

Johan Hovold and committed by
Joerg Roedel
de83d461 b3f1ee18

+18 -7
+18 -7
drivers/iommu/mtk_iommu.c
··· 1213 1213 } 1214 1214 1215 1215 component_match_add(dev, match, component_compare_dev, &plarbdev->dev); 1216 - platform_device_put(plarbdev); 1217 1216 } 1218 1217 1219 - if (!frst_avail_smicomm_node) 1220 - return -EINVAL; 1218 + if (!frst_avail_smicomm_node) { 1219 + ret = -EINVAL; 1220 + goto err_larbdev_put; 1221 + } 1221 1222 1222 1223 pcommdev = of_find_device_by_node(frst_avail_smicomm_node); 1223 1224 of_node_put(frst_avail_smicomm_node); 1224 - if (!pcommdev) 1225 - return -ENODEV; 1225 + if (!pcommdev) { 1226 + ret = -ENODEV; 1227 + goto err_larbdev_put; 1228 + } 1226 1229 data->smicomm_dev = &pcommdev->dev; 1227 1230 1228 1231 link = device_link_add(data->smicomm_dev, dev, ··· 1233 1230 platform_device_put(pcommdev); 1234 1231 if (!link) { 1235 1232 dev_err(dev, "Unable to link %s.\n", dev_name(data->smicomm_dev)); 1236 - return -EINVAL; 1233 + ret = -EINVAL; 1234 + goto err_larbdev_put; 1237 1235 } 1238 1236 return 0; 1239 1237 ··· 1406 1402 iommu_device_sysfs_remove(&data->iommu); 1407 1403 out_list_del: 1408 1404 list_del(&data->list); 1409 - if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) 1405 + if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) { 1410 1406 device_link_remove(data->smicomm_dev, dev); 1407 + 1408 + for (i = 0; i < MTK_LARB_NR_MAX; i++) 1409 + put_device(data->larb_imu[i].dev); 1410 + } 1411 1411 out_runtime_disable: 1412 1412 pm_runtime_disable(dev); 1413 1413 return ret; ··· 1431 1423 if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) { 1432 1424 device_link_remove(data->smicomm_dev, &pdev->dev); 1433 1425 component_master_del(&pdev->dev, &mtk_iommu_com_ops); 1426 + 1427 + for (i = 0; i < MTK_LARB_NR_MAX; i++) 1428 + put_device(data->larb_imu[i].dev); 1434 1429 } 1435 1430 pm_runtime_disable(&pdev->dev); 1436 1431 for (i = 0; i < data->plat_data->banks_num; i++) {