Message ID | 20240130095656.3712469-2-wenst@chromium.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | soc: mediatek: mtk-socinfo: Fixes and cleanup | expand |
Il 30/01/24 10:56, Chen-Yu Tsai ha scritto: > The mtk-socinfo grabs the NVMEM device devm_nvmem_device_get(), but then > proceeds to put the device directly with nvmem_device_put() if the read > is successful. If the device fails to probe and goes through the devres > release path, the device would be put a second time, triggering a > use-after-free error from KASAN. > > Fix this by dropping the devres part. Since the NVMEM cell data is read > only once, there is no need to keep the reference around. > > While at it, clean up the function to directly reference the NVMEM > device node and use that to find the NVMEM device, instead of finding it > by name, which is more fragile. The cell node is always a direct child > of the NVMEM device node, courtesy of the legacy NVMEM cell layout. Thus > of_get_child_by_name() is a better way of finding the cell. Last, > correctly put the device node once its use is over. > > Fixes: 423a54da3c7e ("soc: mediatek: mtk-socinfo: Add driver for getting chip information") > Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
diff --git a/drivers/soc/mediatek/mtk-socinfo.c b/drivers/soc/mediatek/mtk-socinfo.c index 0094f43e1e08..3909d22062ce 100644 --- a/drivers/soc/mediatek/mtk-socinfo.c +++ b/drivers/soc/mediatek/mtk-socinfo.c @@ -9,6 +9,7 @@ #include <linux/pm_runtime.h> #include <linux/nvmem-consumer.h> #include <linux/device.h> +#include <linux/device/bus.h> #include <linux/debugfs.h> #include <linux/seq_file.h> #include <linux/string.h> @@ -82,25 +83,28 @@ static int mtk_socinfo_create_socinfo_node(struct mtk_socinfo *mtk_socinfop) static u32 mtk_socinfo_read_cell(struct device *dev, const char *name) { struct nvmem_device *nvmemp; - struct device_node *np = dev->of_node; + struct device_node *np, *nvmem_node = dev->parent->of_node; u32 offset; u32 cell_val = CELL_NOT_USED; - nvmemp = devm_nvmem_device_get(dev, "mtk-efuse0"); + /* should never fail since the nvmem driver registers this child */ + nvmemp = nvmem_device_find(nvmem_node, device_match_of_node); if (IS_ERR(nvmemp)) goto out; - np = of_find_node_by_name(NULL, name); + np = of_get_child_by_name(nvmem_node, name); if (!np) - goto out; + goto put_device; if (of_property_read_u32_index(np, "reg", 0, &offset)) - goto out; + goto put_node; nvmem_device_read(nvmemp, offset, sizeof(cell_val), &cell_val); +put_node: + of_node_put(np); +put_device: nvmem_device_put(nvmemp); - out: return cell_val; }
The mtk-socinfo grabs the NVMEM device devm_nvmem_device_get(), but then proceeds to put the device directly with nvmem_device_put() if the read is successful. If the device fails to probe and goes through the devres release path, the device would be put a second time, triggering a use-after-free error from KASAN. Fix this by dropping the devres part. Since the NVMEM cell data is read only once, there is no need to keep the reference around. While at it, clean up the function to directly reference the NVMEM device node and use that to find the NVMEM device, instead of finding it by name, which is more fragile. The cell node is always a direct child of the NVMEM device node, courtesy of the legacy NVMEM cell layout. Thus of_get_child_by_name() is a better way of finding the cell. Last, correctly put the device node once its use is over. Fixes: 423a54da3c7e ("soc: mediatek: mtk-socinfo: Add driver for getting chip information") Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> --- drivers/soc/mediatek/mtk-socinfo.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)