linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] regset: use vmalloc() for regset_get_alloc()
@ 2024-02-02  1:12 Douglas Anderson
  2024-02-02  1:22 ` Al Viro
  2024-02-02  1:24 ` Matthew Wilcox
  0 siblings, 2 replies; 17+ messages in thread
From: Douglas Anderson @ 2024-02-02  1:12 UTC (permalink / raw)
  To: Alexander Viro, Christian Brauner
  Cc: Douglas Anderson, Eric Biederman, Jan Kara, Kees Cook,
	linux-fsdevel, linux-kernel, linux-mm

While browsing through ChromeOS crash reports, I found one with an
allocation failure that looked like this:

  chrome: page allocation failure: order:7,
          mode:0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO),
	  nodemask=(null),cpuset=urgent,mems_allowed=0
  CPU: 7 PID: 3295 Comm: chrome Not tainted
          5.15.133-20574-g8044615ac35c #1 (HASH:1162 1)
  Hardware name: Google Lazor (rev3 - 8) with KB Backlight (DT)
  Call trace:
  dump_backtrace+0x0/0x1ec
  show_stack+0x20/0x2c
  dump_stack_lvl+0x60/0x78
  dump_stack+0x18/0x38
  warn_alloc+0x104/0x174
  __alloc_pages+0x5f0/0x6e4
  kmalloc_order+0x44/0x98
  kmalloc_order_trace+0x34/0x124
  __kmalloc+0x228/0x36c
  __regset_get+0x68/0xcc
  regset_get_alloc+0x1c/0x28
  elf_core_dump+0x3d8/0xd8c
  do_coredump+0xeb8/0x1378
  get_signal+0x14c/0x804
  ...

An order 7 allocation is (1 << 7) contiguous pages, or 512K. It's not
a surprise that this allocation failed on a system that's been running
for a while.

In this case we're just generating a core dump and there's no reason
we need contiguous memory. Change the allocation to vmalloc(). We'll
change the free in binfmt_elf to kvfree() which works regardless of
how the memory was allocated.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
I don't know this code at all, but I _think_ I've identified the
places where the memory is freed correctly. Please double-check that I
didn't miss anything obvious, though!

 fs/binfmt_elf.c | 2 +-
 kernel/regset.c | 7 ++++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 5397b552fbeb..ac178ad38823 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1928,7 +1928,7 @@ static void free_note_info(struct elf_note_info *info)
 		threads = t->next;
 		WARN_ON(t->notes[0].data && t->notes[0].data != &t->prstatus);
 		for (i = 1; i < info->thread_notes; ++i)
-			kfree(t->notes[i].data);
+			kvfree(t->notes[i].data);
 		kfree(t);
 	}
 	kfree(info->psinfo.data);
diff --git a/kernel/regset.c b/kernel/regset.c
index 586823786f39..ed8d8cf3a22c 100644
--- a/kernel/regset.c
+++ b/kernel/regset.c
@@ -2,6 +2,7 @@
 #include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/regset.h>
+#include <linux/vmalloc.h>
 
 static int __regset_get(struct task_struct *target,
 			const struct user_regset *regset,
@@ -16,14 +17,14 @@ static int __regset_get(struct task_struct *target,
 	if (size > regset->n * regset->size)
 		size = regset->n * regset->size;
 	if (!p) {
-		to_free = p = kzalloc(size, GFP_KERNEL);
+		to_free = p = vmalloc(size);
 		if (!p)
 			return -ENOMEM;
 	}
 	res = regset->regset_get(target, regset,
 			   (struct membuf){.p = p, .left = size});
 	if (res < 0) {
-		kfree(to_free);
+		vfree(to_free);
 		return res;
 	}
 	*data = p;
@@ -71,6 +72,6 @@ int copy_regset_to_user(struct task_struct *target,
 	ret = regset_get_alloc(target, regset, size, &buf);
 	if (ret > 0)
 		ret = copy_to_user(data, buf, ret) ? -EFAULT : 0;
-	kfree(buf);
+	vfree(buf);
 	return ret;
 }
-- 
2.43.0.594.gd9cf4e227d-goog


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

end of thread, other threads:[~2024-02-02 20:47 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-02  1:12 [PATCH] regset: use vmalloc() for regset_get_alloc() Douglas Anderson
2024-02-02  1:22 ` Al Viro
2024-02-02  2:54   ` Doug Anderson
2024-02-02  3:04     ` Al Viro
2024-02-02  3:15       ` Doug Anderson
2024-02-02  3:49         ` Al Viro
2024-02-02  4:05           ` Al Viro
2024-02-02 16:24             ` Doug Anderson
2024-02-02 16:49               ` Al Viro
2024-02-02 16:55                 ` Al Viro
2024-02-02 18:07                   ` Dave Martin
2024-02-02 19:13                     ` Doug Anderson
2024-02-02 19:42                     ` Mark Brown
2024-02-02 20:38                       ` Doug Anderson
2024-02-02 17:48           ` Mark Brown
2024-02-02  1:24 ` Matthew Wilcox
2024-02-02  2:58   ` Doug Anderson

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).