diff options
author | Johannes Berg <johannes.berg@intel.com> | 2020-12-05 21:50:18 +0100 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2020-12-13 22:38:06 +0100 |
commit | ef4459a6da0955b533ebfc97a7d756ac090f50c9 (patch) | |
tree | 5c1153080467c99b2f60942757f644d38338319b /arch/um/kernel | |
parent | um: support some of ARCH_HAS_SET_MEMORY (diff) | |
download | linux-ef4459a6da0955b533ebfc97a7d756ac090f50c9.tar.xz linux-ef4459a6da0955b533ebfc97a7d756ac090f50c9.zip |
um: allocate a guard page to helper threads
We've been running into stack overflows in helper threads
corrupting memory (e.g. because somebody put printf() or
os_info() there), so to avoid those causing hard-to-debug
issues later on, allocate a guard page for helper thread
stacks and mark it read-only.
Unfortunately, the crash dump at that point is useless as
the stack tracer will try to backtrace the *kernel* thread,
not the helper thread, but at least we don't survive to a
random issue caused by corruption.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'arch/um/kernel')
-rw-r--r-- | arch/um/kernel/process.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 81d508daf67c..2a986ece5478 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -32,6 +32,7 @@ #include <os.h> #include <skas.h> #include <linux/time-internal.h> +#include <asm/set_memory.h> /* * This is a per-cpu array. A processor only modifies its entry and it only @@ -62,16 +63,18 @@ void free_stack(unsigned long stack, int order) free_pages(stack, order); } -unsigned long alloc_stack(int order, int atomic) +unsigned long alloc_stack(int atomic) { - unsigned long page; + unsigned long addr; gfp_t flags = GFP_KERNEL; if (atomic) flags = GFP_ATOMIC; - page = __get_free_pages(flags, order); + addr = __get_free_pages(flags, 1); - return page; + set_memory_ro(addr, 1); + + return addr + PAGE_SIZE; } static inline void set_current(struct task_struct *task) |