linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] iommu: Fix missing check for return value of iommu_group_get()
@ 2023-06-14 15:43 Chenyuan Mi
  2023-06-14 16:29 ` Robin Murphy
  2023-06-15  2:31 ` Baolu Lu
  0 siblings, 2 replies; 3+ messages in thread
From: Chenyuan Mi @ 2023-06-14 15:43 UTC (permalink / raw)
  To: joro; +Cc: will, robin.murphy, iommu, linux-kernel, Chenyuan Mi

The iommu_group_get() function may return NULL, which may
cause null pointer deference, and most other callsites of
iommu_group_get() do Null check. Add Null check for return
value of iommu_group_get().

Found by our static analysis tool.

Signed-off-by: Chenyuan Mi <cymi20@fudan.edu.cn>
---
 drivers/iommu/iommu.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index f1dcfa3f1a1b..ef3483e75511 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3217,6 +3217,8 @@ EXPORT_SYMBOL_GPL(iommu_group_release_dma_owner);
 void iommu_device_release_dma_owner(struct device *dev)
 {
 	struct iommu_group *group = iommu_group_get(dev);
+	if (!group)
+		return;
 
 	mutex_lock(&group->mutex);
 	if (group->owner_cnt > 1)
@@ -3329,6 +3331,8 @@ void iommu_detach_device_pasid(struct iommu_domain *domain, struct device *dev,
 			       ioasid_t pasid)
 {
 	struct iommu_group *group = iommu_group_get(dev);
+	if (!group)
+		return;
 
 	mutex_lock(&group->mutex);
 	__iommu_remove_group_pasid(group, pasid);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] iommu: Fix missing check for return value of iommu_group_get()
  2023-06-14 15:43 [PATCH] iommu: Fix missing check for return value of iommu_group_get() Chenyuan Mi
@ 2023-06-14 16:29 ` Robin Murphy
  2023-06-15  2:31 ` Baolu Lu
  1 sibling, 0 replies; 3+ messages in thread
From: Robin Murphy @ 2023-06-14 16:29 UTC (permalink / raw)
  To: Chenyuan Mi, joro; +Cc: will, iommu, linux-kernel

On 2023-06-14 16:43, Chenyuan Mi wrote:
> The iommu_group_get() function may return NULL, which may
> cause null pointer deference, and most other callsites of
> iommu_group_get() do Null check. Add Null check for return
> value of iommu_group_get().
> 
> Found by our static analysis tool.

Static analysis is good at highlighting areas of code that might be 
worth looking at, but you then still need to actually look at the code 
and understand whether there's a problem or not...

> Signed-off-by: Chenyuan Mi <cymi20@fudan.edu.cn>
> ---
>   drivers/iommu/iommu.c | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index f1dcfa3f1a1b..ef3483e75511 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -3217,6 +3217,8 @@ EXPORT_SYMBOL_GPL(iommu_group_release_dma_owner);

/**
  * iommu_group_release_dma_owner() - Release DMA ownership of a group
  * @dev: The device
  *
  * Release the DMA ownership claimed by iommu_group_claim_dma_owner().
  */

If dev->iommu_group could have somehow disappeared since 
iommu_group_claim_dma_owner() succeeded then something has gone so 
catastrophically wrong that it's not worth even trying to reason about. 
Or if the caller is passing something here that isn't the same device, 
then why should we assume it's even a valid device pointer at all, and 
iommu_group_get() isn't going to crash or return nonzero garbage?

>   void iommu_device_release_dma_owner(struct device *dev)
>   {
>   	struct iommu_group *group = iommu_group_get(dev);
> +	if (!group)
> +		return;
>   
>   	mutex_lock(&group->mutex);
>   	if (group->owner_cnt > 1)
> @@ -3329,6 +3331,8 @@ void iommu_detach_device_pasid(struct iommu_domain *domain, struct device *dev,
>   			       ioasid_t pasid)

/*
  * iommu_detach_device_pasid() - Detach the domain from pasid of device
  * @domain: the iommu domain.
  * @dev: the attached device.
  * @pasid: the pasid of the device.
  *
  * The @domain must have been attached to @pasid of the @dev with
  * iommu_attach_device_pasid().
  */

Again, iommu_attach_device_pasid() already validates that the device has 
a group. If a caller uses the API incorrectly then all bets are off. 
Plus, look at the callsites of iommu_detach_device_pasid() - they're 
already holding their own reference to the same group anyway!

Thanks,
Robin.

>   {
>   	struct iommu_group *group = iommu_group_get(dev);
> +	if (!group)
> +		return;
>   
>   	mutex_lock(&group->mutex);
>   	__iommu_remove_group_pasid(group, pasid);

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] iommu: Fix missing check for return value of iommu_group_get()
  2023-06-14 15:43 [PATCH] iommu: Fix missing check for return value of iommu_group_get() Chenyuan Mi
  2023-06-14 16:29 ` Robin Murphy
@ 2023-06-15  2:31 ` Baolu Lu
  1 sibling, 0 replies; 3+ messages in thread
From: Baolu Lu @ 2023-06-15  2:31 UTC (permalink / raw)
  To: Chenyuan Mi, joro; +Cc: baolu.lu, will, robin.murphy, iommu, linux-kernel

On 6/14/23 11:43 PM, Chenyuan Mi wrote:
> The iommu_group_get() function may return NULL, which may
> cause null pointer deference, and most other callsites of
> iommu_group_get() do Null check. Add Null check for return
> value of iommu_group_get().
> 
> Found by our static analysis tool.
> 
> Signed-off-by: Chenyuan Mi <cymi20@fudan.edu.cn>
> ---
>   drivers/iommu/iommu.c | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index f1dcfa3f1a1b..ef3483e75511 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -3217,6 +3217,8 @@ EXPORT_SYMBOL_GPL(iommu_group_release_dma_owner);
>   void iommu_device_release_dma_owner(struct device *dev)
>   {
>   	struct iommu_group *group = iommu_group_get(dev);
> +	if (!group)
> +		return;

This interface should never be used in this way.

Check the comments of this function:

"Release the DMA ownership claimed by iommu_device_claim_dma_owner()."

iommu group has been checked in the claim api.

If any driver misuses this api, a null pointer deference warning is
better than ignoring silently.

>   
>   	mutex_lock(&group->mutex);
>   	if (group->owner_cnt > 1)
> @@ -3329,6 +3331,8 @@ void iommu_detach_device_pasid(struct iommu_domain *domain, struct device *dev,
>   			       ioasid_t pasid)
>   {
>   	struct iommu_group *group = iommu_group_get(dev);
> +	if (!group)
> +		return;

Ditto...

>   
>   	mutex_lock(&group->mutex);
>   	__iommu_remove_group_pasid(group, pasid);

Best regards,
baolu

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-06-15  2:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-14 15:43 [PATCH] iommu: Fix missing check for return value of iommu_group_get() Chenyuan Mi
2023-06-14 16:29 ` Robin Murphy
2023-06-15  2:31 ` Baolu Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).