drm: Use kvzalloc for allocating blob property memory
diff mbox

Message ID 20180629142710.2069-1-michel@daenzer.net
State New
Headers show

Commit Message

Michel Dänzer June 29, 2018, 2:27 p.m. UTC
From: Michel Dänzer <michel.daenzer@amd.com>

The property size may be controlled by userspace, can be large (I've
seen failure with order 4, i.e. 16 pages / 64 KB) and doesn't need to be
physically contiguous.

Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
---
 drivers/gpu/drm/drm_property.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Comments

Alex Deucher June 29, 2018, 2:50 p.m. UTC | #1
On Fri, Jun 29, 2018 at 10:27 AM, Michel Dänzer <michel@daenzer.net> wrote:
> From: Michel Dänzer <michel.daenzer@amd.com>
>
> The property size may be controlled by userspace, can be large (I've
> seen failure with order 4, i.e. 16 pages / 64 KB) and doesn't need to be
> physically contiguous.
>
> Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/drm_property.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
> index 1f8031e30f53..cdb10f885a4f 100644
> --- a/drivers/gpu/drm/drm_property.c
> +++ b/drivers/gpu/drm/drm_property.c
> @@ -532,7 +532,7 @@ static void drm_property_free_blob(struct kref *kref)
>
>         drm_mode_object_unregister(blob->dev, &blob->base);
>
> -       kfree(blob);
> +       kvfree(blob);
>  }
>
>  /**
> @@ -559,7 +559,7 @@ drm_property_create_blob(struct drm_device *dev, size_t length,
>         if (!length || length > ULONG_MAX - sizeof(struct drm_property_blob))
>                 return ERR_PTR(-EINVAL);
>
> -       blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
> +       blob = kvzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
>         if (!blob)
>                 return ERR_PTR(-ENOMEM);
>
> @@ -576,7 +576,7 @@ drm_property_create_blob(struct drm_device *dev, size_t length,
>         ret = __drm_mode_object_add(dev, &blob->base, DRM_MODE_OBJECT_BLOB,
>                                     true, drm_property_free_blob);
>         if (ret) {
> -               kfree(blob);
> +               kvfree(blob);
>                 return ERR_PTR(-EINVAL);
>         }
>
> --
> 2.18.0
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
Ville Syrjälä June 29, 2018, 4:12 p.m. UTC | #2
On Fri, Jun 29, 2018 at 04:27:10PM +0200, Michel Dänzer wrote:
> From: Michel Dänzer <michel.daenzer@amd.com>
> 
> The property size may be controlled by userspace, can be large (I've
> seen failure with order 4, i.e. 16 pages / 64 KB) and doesn't need to be
> physically contiguous.

I wonder if we should enforce some kind of reasonable limit
on the blob size. Looks like we allow anything up to
ULONG_MAX currently. We can't tell at createblob time how
the thing is going to be used, so can't have any kind
of property specific limit unfortunately.

> 
> Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
> ---
>  drivers/gpu/drm/drm_property.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
> index 1f8031e30f53..cdb10f885a4f 100644
> --- a/drivers/gpu/drm/drm_property.c
> +++ b/drivers/gpu/drm/drm_property.c
> @@ -532,7 +532,7 @@ static void drm_property_free_blob(struct kref *kref)
>  
>  	drm_mode_object_unregister(blob->dev, &blob->base);
>  
> -	kfree(blob);
> +	kvfree(blob);
>  }
>  
>  /**
> @@ -559,7 +559,7 @@ drm_property_create_blob(struct drm_device *dev, size_t length,
>  	if (!length || length > ULONG_MAX - sizeof(struct drm_property_blob))
>  		return ERR_PTR(-EINVAL);
>  
> -	blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
> +	blob = kvzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
>  	if (!blob)
>  		return ERR_PTR(-ENOMEM);
>  
> @@ -576,7 +576,7 @@ drm_property_create_blob(struct drm_device *dev, size_t length,
>  	ret = __drm_mode_object_add(dev, &blob->base, DRM_MODE_OBJECT_BLOB,
>  				    true, drm_property_free_blob);
>  	if (ret) {
> -		kfree(blob);
> +		kvfree(blob);
>  		return ERR_PTR(-EINVAL);
>  	}
>  
> -- 
> 2.18.0
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
Michel Dänzer June 29, 2018, 4:27 p.m. UTC | #3
On 2018-06-29 06:12 PM, Ville Syrjälä wrote:
> On Fri, Jun 29, 2018 at 04:27:10PM +0200, Michel Dänzer wrote:
>> From: Michel Dänzer <michel.daenzer@amd.com>
>>
>> The property size may be controlled by userspace, can be large (I've
>> seen failure with order 4, i.e. 16 pages / 64 KB) and doesn't need to be
>> physically contiguous.
> 
> I wonder if we should enforce some kind of reasonable limit
> on the blob size. Looks like we allow anything up to
> ULONG_MAX currently. We can't tell at createblob time how
> the thing is going to be used, so can't have any kind
> of property specific limit unfortunately.

The failure I was seeing was for a gamma LUT, so a size limit alone
cannot solve the issue.
Ville Syrjälä June 29, 2018, 4:38 p.m. UTC | #4
On Fri, Jun 29, 2018 at 06:27:28PM +0200, Michel Dänzer wrote:
> On 2018-06-29 06:12 PM, Ville Syrjälä wrote:
> > On Fri, Jun 29, 2018 at 04:27:10PM +0200, Michel Dänzer wrote:
> >> From: Michel Dänzer <michel.daenzer@amd.com>
> >>
> >> The property size may be controlled by userspace, can be large (I've
> >> seen failure with order 4, i.e. 16 pages / 64 KB) and doesn't need to be
> >> physically contiguous.
> > 
> > I wonder if we should enforce some kind of reasonable limit
> > on the blob size. Looks like we allow anything up to
> > ULONG_MAX currently. We can't tell at createblob time how
> > the thing is going to be used, so can't have any kind
> > of property specific limit unfortunately.
> 
> The failure I was seeing was for a gamma LUT, so a size limit alone
> cannot solve the issue.

Sure. I was just thinking that maybe we shouldn't allow someone to
allocate unlimited amounts of kernel memory via this interface. But
to do that effectively we'd also need to limit the total amount used
by all blobs.
Daniel Vetter July 2, 2018, 8:07 a.m. UTC | #5
On Fri, Jun 29, 2018 at 07:38:32PM +0300, Ville Syrjälä wrote:
> On Fri, Jun 29, 2018 at 06:27:28PM +0200, Michel Dänzer wrote:
> > On 2018-06-29 06:12 PM, Ville Syrjälä wrote:
> > > On Fri, Jun 29, 2018 at 04:27:10PM +0200, Michel Dänzer wrote:
> > >> From: Michel Dänzer <michel.daenzer@amd.com>
> > >>
> > >> The property size may be controlled by userspace, can be large (I've
> > >> seen failure with order 4, i.e. 16 pages / 64 KB) and doesn't need to be
> > >> physically contiguous.
> > > 
> > > I wonder if we should enforce some kind of reasonable limit
> > > on the blob size. Looks like we allow anything up to
> > > ULONG_MAX currently. We can't tell at createblob time how
> > > the thing is going to be used, so can't have any kind
> > > of property specific limit unfortunately.
> > 
> > The failure I was seeing was for a gamma LUT, so a size limit alone
> > cannot solve the issue.
> 
> Sure. I was just thinking that maybe we shouldn't allow someone to
> allocate unlimited amounts of kernel memory via this interface. But
> to do that effectively we'd also need to limit the total amount used
> by all blobs.

People with drm master rights are allowed to pin enormous amounts of
memory (through pinning of display buffers) ... I think simply requiring
DRM_MASTER for the ioctl would be good enough. Atm anyone can abuse
createblob to waste memory, which is a bit much.

We haven't marked it with DRM_RENDER_ALLOW, so I think this is just an
oversight really. I'll type a patch.
-Daniel

Patch
diff mbox

diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
index 1f8031e30f53..cdb10f885a4f 100644
--- a/drivers/gpu/drm/drm_property.c
+++ b/drivers/gpu/drm/drm_property.c
@@ -532,7 +532,7 @@  static void drm_property_free_blob(struct kref *kref)
 
 	drm_mode_object_unregister(blob->dev, &blob->base);
 
-	kfree(blob);
+	kvfree(blob);
 }
 
 /**
@@ -559,7 +559,7 @@  drm_property_create_blob(struct drm_device *dev, size_t length,
 	if (!length || length > ULONG_MAX - sizeof(struct drm_property_blob))
 		return ERR_PTR(-EINVAL);
 
-	blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
+	blob = kvzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
 	if (!blob)
 		return ERR_PTR(-ENOMEM);
 
@@ -576,7 +576,7 @@  drm_property_create_blob(struct drm_device *dev, size_t length,
 	ret = __drm_mode_object_add(dev, &blob->base, DRM_MODE_OBJECT_BLOB,
 				    true, drm_property_free_blob);
 	if (ret) {
-		kfree(blob);
+		kvfree(blob);
 		return ERR_PTR(-EINVAL);
 	}