| From 8b9ad480bd1dd25f4ff4854af5685fa334a2f57a Mon Sep 17 00:00:00 2001 |
| From: Xiaomeng Tong <xiam0nd.tong@gmail.com> |
| Date: Sun, 1 May 2022 21:28:23 +0800 |
| Subject: iommu/msm: Fix an incorrect NULL check on list iterator |
| |
| From: Xiaomeng Tong <xiam0nd.tong@gmail.com> |
| |
| commit 8b9ad480bd1dd25f4ff4854af5685fa334a2f57a upstream. |
| |
| The bug is here: |
| if (!iommu || iommu->dev->of_node != spec->np) { |
| |
| The list iterator value 'iommu' will *always* be set and non-NULL by |
| list_for_each_entry(), so it is incorrect to assume that the iterator |
| value will be NULL if the list is empty or no element is found (in fact, |
| it will point to a invalid structure object containing HEAD). |
| |
| To fix the bug, use a new value 'iter' as the list iterator, while use |
| the old value 'iommu' as a dedicated variable to point to the found one, |
| and remove the unneeded check for 'iommu->dev->of_node != spec->np' |
| outside the loop. |
| |
| Cc: stable@vger.kernel.org |
| Fixes: f78ebca8ff3d6 ("iommu/msm: Add support for generic master bindings") |
| Signed-off-by: Xiaomeng Tong <xiam0nd.tong@gmail.com> |
| Link: https://lore.kernel.org/r/20220501132823.12714-1-xiam0nd.tong@gmail.com |
| Signed-off-by: Joerg Roedel <jroedel@suse.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/iommu/msm_iommu.c | 11 +++++++---- |
| 1 file changed, 7 insertions(+), 4 deletions(-) |
| |
| --- a/drivers/iommu/msm_iommu.c |
| +++ b/drivers/iommu/msm_iommu.c |
| @@ -580,16 +580,19 @@ static void insert_iommu_master(struct d |
| static int qcom_iommu_of_xlate(struct device *dev, |
| struct of_phandle_args *spec) |
| { |
| - struct msm_iommu_dev *iommu; |
| + struct msm_iommu_dev *iommu = NULL, *iter; |
| unsigned long flags; |
| int ret = 0; |
| |
| spin_lock_irqsave(&msm_iommu_lock, flags); |
| - list_for_each_entry(iommu, &qcom_iommu_devices, dev_node) |
| - if (iommu->dev->of_node == spec->np) |
| + list_for_each_entry(iter, &qcom_iommu_devices, dev_node) { |
| + if (iter->dev->of_node == spec->np) { |
| + iommu = iter; |
| break; |
| + } |
| + } |
| |
| - if (!iommu || iommu->dev->of_node != spec->np) { |
| + if (!iommu) { |
| ret = -ENODEV; |
| goto fail; |
| } |