| From f0b6742cee54097003e23e28df53f415e9340fe2 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 25 Feb 2021 17:20:49 -0800 |
| Subject: proc: use kvzalloc for our kernel buffer |
| |
| From: Josef Bacik <josef@toxicpanda.com> |
| |
| [ Upstream commit 4508943794efdd94171549c0bd52810e2f4ad9fe ] |
| |
| 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 blindly kzalloc()'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, so |
| use kvzalloc for these buffers. |
| |
| [willy@infradead.org: changelog tweaks] |
| |
| Link: https://lkml.kernel.org/r/6345270a2c1160b89dd5e6715461f388176899d1.1612972413.git.josef@toxicpanda.com |
| 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> |
| Cc: Al Viro <viro@zeniv.linux.org.uk> |
| Cc: Alexey Dobriyan <adobriyan@gmail.com> |
| CC: Matthew Wilcox <willy@infradead.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| 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 d2018f70d1fae..070d2df8ab9cf 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.27.0 |
| |