diff mbox series

proc: use vmalloc for our kernel buffer

Message ID 6345270a2c1160b89dd5e6715461f388176899d1.1612972413.git.josef@toxicpanda.com (mailing list archive)
State New, archived
Headers show
Series proc: use vmalloc for our kernel buffer | expand

Commit Message

Josef Bacik Feb. 10, 2021, 3:54 p.m. UTC
Since

  sysctl: pass kernel pointers to ->proc_handler

we have been pre-allocating a buffer to copy the data from the proc
handlers into, and then copying that to userspace.  The problem is this
just blind kmalloc()'s the buffer size passed in from the read, which in
the case of our 'cat' binary was 64kib.  Order-4 allocations are not
awesome, and since we can potentially allocate up to our maximum order,
use vmalloc for these buffers.

Fixes: 32927393dc1c ("sysctl: pass kernel pointers to ->proc_handler")
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 fs/proc/proc_sysctl.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Vlastimil Babka Feb. 10, 2021, 5:16 p.m. UTC | #1
On 2/10/21 4:54 PM, Josef Bacik wrote:
> Since
> 
>   sysctl: pass kernel pointers to ->proc_handler
> 
> we have been pre-allocating a buffer to copy the data from the proc
> handlers into, and then copying that to userspace.  The problem is this
> just blind kmalloc()'s the buffer size passed in from the read, which in
> the case of our 'cat' binary was 64kib.  Order-4 allocations are not
> awesome, and since we can potentially allocate up to our maximum order,
> use vmalloc for these buffers.
> 
> Fixes: 32927393dc1c ("sysctl: pass kernel pointers to ->proc_handler")
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> Reviewed-by: Christoph Hellwig <hch@lst.de>

Acked-by: Vlastimil Babka <vbabka@suse.cz>

> ---
>  fs/proc/proc_sysctl.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
> index d2018f70d1fa..070d2df8ab9c 100644
> --- a/fs/proc/proc_sysctl.c
> +++ b/fs/proc/proc_sysctl.c
> @@ -571,7 +571,7 @@ static ssize_t proc_sys_call_handler(struct kiocb *iocb, struct iov_iter *iter,
>  	error = -ENOMEM;
>  	if (count >= KMALLOC_MAX_SIZE)
>  		goto out;
> -	kbuf = kzalloc(count + 1, GFP_KERNEL);
> +	kbuf = kvzalloc(count + 1, GFP_KERNEL);
>  	if (!kbuf)
>  		goto out;
>  
> @@ -600,7 +600,7 @@ static ssize_t proc_sys_call_handler(struct kiocb *iocb, struct iov_iter *iter,
>  
>  	error = count;
>  out_free_buf:
> -	kfree(kbuf);
> +	kvfree(kbuf);
>  out:
>  	sysctl_head_finish(head);
>  
>
Matthew Wilcox Feb. 10, 2021, 6:15 p.m. UTC | #2
s/vmalloc/kvmalloc/g

Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>

On Wed, Feb 10, 2021 at 10:54:24AM -0500, Josef Bacik wrote:
> Since
> 
>   sysctl: pass kernel pointers to ->proc_handler
> 
> we have been pre-allocating a buffer to copy the data from the proc
> handlers into, and then copying that to userspace.  The problem is this
> just blind kmalloc()'s the buffer size passed in from the read, which in
> the case of our 'cat' binary was 64kib.  Order-4 allocations are not
> awesome, and since we can potentially allocate up to our maximum order,
> use vmalloc for these buffers.
> 
> Fixes: 32927393dc1c ("sysctl: pass kernel pointers to ->proc_handler")
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/proc/proc_sysctl.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
> index d2018f70d1fa..070d2df8ab9c 100644
> --- a/fs/proc/proc_sysctl.c
> +++ b/fs/proc/proc_sysctl.c
> @@ -571,7 +571,7 @@ static ssize_t proc_sys_call_handler(struct kiocb *iocb, struct iov_iter *iter,
>  	error = -ENOMEM;
>  	if (count >= KMALLOC_MAX_SIZE)
>  		goto out;
> -	kbuf = kzalloc(count + 1, GFP_KERNEL);
> +	kbuf = kvzalloc(count + 1, GFP_KERNEL);
>  	if (!kbuf)
>  		goto out;
>  
> @@ -600,7 +600,7 @@ static ssize_t proc_sys_call_handler(struct kiocb *iocb, struct iov_iter *iter,
>  
>  	error = count;
>  out_free_buf:
> -	kfree(kbuf);
> +	kvfree(kbuf);
>  out:
>  	sysctl_head_finish(head);
>  
> -- 
> 2.26.2
>
diff mbox series

Patch

diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index d2018f70d1fa..070d2df8ab9c 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -571,7 +571,7 @@  static ssize_t proc_sys_call_handler(struct kiocb *iocb, struct iov_iter *iter,
 	error = -ENOMEM;
 	if (count >= KMALLOC_MAX_SIZE)
 		goto out;
-	kbuf = kzalloc(count + 1, GFP_KERNEL);
+	kbuf = kvzalloc(count + 1, GFP_KERNEL);
 	if (!kbuf)
 		goto out;
 
@@ -600,7 +600,7 @@  static ssize_t proc_sys_call_handler(struct kiocb *iocb, struct iov_iter *iter,
 
 	error = count;
 out_free_buf:
-	kfree(kbuf);
+	kvfree(kbuf);
 out:
 	sysctl_head_finish(head);