[PATCH] drm/v3d: Fix perfmon reference leak in v3d_perfmon_set_global_ioctl()

Wentao Liang posted 1 patch 1 week, 1 day ago
drivers/gpu/drm/v3d/v3d_perfmon.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
[PATCH] drm/v3d: Fix perfmon reference leak in v3d_perfmon_set_global_ioctl()
Posted by Wentao Liang 1 week, 1 day ago
v3d_perfmon_find() takes a reference to the perfmon which the ioctl
transfers to the global pointer on success.  The error paths are
missing this transfer: clearing the global perfmon while none is set,
and setting a global perfmon when one is already configured both
return without dropping the reference.  Release it on both paths.

Fixes: c6eabbab359c ("drm/v3d: Add DRM_IOCTL_V3D_PERFMON_SET_GLOBAL")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
---
 drivers/gpu/drm/v3d/v3d_perfmon.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/v3d/v3d_perfmon.c b/drivers/gpu/drm/v3d/v3d_perfmon.c
index 8e0249580bba..12bb1b087fa9 100644
--- a/drivers/gpu/drm/v3d/v3d_perfmon.c
+++ b/drivers/gpu/drm/v3d/v3d_perfmon.c
@@ -461,16 +461,20 @@ int v3d_perfmon_set_global_ioctl(struct drm_device *dev, void *data,
 
 	/* If the request is to clear the global performance monitor */
 	if (req->flags & DRM_V3D_PERFMON_CLEAR_GLOBAL) {
-		if (!v3d->global_perfmon)
+		if (!v3d->global_perfmon) {
+			v3d_perfmon_put(perfmon);
 			return -EINVAL;
+		}
 
 		xchg(&v3d->global_perfmon, NULL);
 
 		return 0;
 	}
 
-	if (cmpxchg(&v3d->global_perfmon, NULL, perfmon))
+	if (cmpxchg(&v3d->global_perfmon, NULL, perfmon)) {
+		v3d_perfmon_put(perfmon);
 		return -EBUSY;
+	}
 
 	return 0;
 }
-- 
2.34.1
Re: [PATCH] drm/v3d: Fix perfmon reference leak in v3d_perfmon_set_global_ioctl()
Posted by Maíra Canal 1 week ago
Hi Wentao,

On 16/09/26 15:31, Wentao Liang wrote:
> v3d_perfmon_find() takes a reference to the perfmon which the ioctl
> transfers to the global pointer on success.  The error paths are
> missing this transfer: clearing the global perfmon while none is set,
> and setting a global perfmon when one is already configured both
> return without dropping the reference.  Release it on both paths.
> 
> Fixes: c6eabbab359c ("drm/v3d: Add DRM_IOCTL_V3D_PERFMON_SET_GLOBAL")
> Cc: stable@vger.kernel.org
> Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>

Already addressed in [1].

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6bf7e2affc6e62da7add393d7f352d4040f5bc27

Best regards,
- Maíra

> ---
>   drivers/gpu/drm/v3d/v3d_perfmon.c | 8 ++++++--
>   1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/v3d/v3d_perfmon.c b/drivers/gpu/drm/v3d/v3d_perfmon.c
> index 8e0249580bba..12bb1b087fa9 100644
> --- a/drivers/gpu/drm/v3d/v3d_perfmon.c
> +++ b/drivers/gpu/drm/v3d/v3d_perfmon.c
> @@ -461,16 +461,20 @@ int v3d_perfmon_set_global_ioctl(struct drm_device *dev, void *data,
>   
>   	/* If the request is to clear the global performance monitor */
>   	if (req->flags & DRM_V3D_PERFMON_CLEAR_GLOBAL) {
> -		if (!v3d->global_perfmon)
> +		if (!v3d->global_perfmon) {
> +			v3d_perfmon_put(perfmon);
>   			return -EINVAL;
> +		}
>   
>   		xchg(&v3d->global_perfmon, NULL);
>   
>   		return 0;
>   	}
>   
> -	if (cmpxchg(&v3d->global_perfmon, NULL, perfmon))
> +	if (cmpxchg(&v3d->global_perfmon, NULL, perfmon)) {
> +		v3d_perfmon_put(perfmon);
>   		return -EBUSY;
> +	}
>   
>   	return 0;
>   }