bus_find_device_by_fwnode() returns a device with its reference count
incremented. arm_smmu_get_by_fwnode() drops that reference before
reading the driver data, which leaves the returned pointer derived from
a device after its reference has been released.
Read the driver data before put_device() and return NULL directly when
the lookup fails.
Signed-off-by: weimin xiong <redacted>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index a10affb48..ef53dd703 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3980,9 +3980,15 @@ static
struct arm_smmu_device *arm_smmu_get_by_fwnode(struct fwnode_handle *fwnode)
{
struct device *dev = bus_find_device_by_fwnode(&platform_bus_type, fwnode);
+ struct arm_smmu_device *smmu;
+
+ if (!dev)
+ return NULL;
+ smmu = dev_get_drvdata(dev);
put_device(dev);
- return dev ? dev_get_drvdata(dev) : NULL;
+
+ return smmu;
}
static bool arm_smmu_sid_in_range(struct arm_smmu_device *smmu, u32 sid)--
2.43.0