From e0521cfb9d2d82bc2f99f39c132db4a0a082ac55 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 19 Dec 2021 18:16:15 +0100 Subject: [PATCH] Kernel: Stop ProcFS stack walk on bogus userspace->kernel traversal Unsurprisingly, the /proc/PID/stacks/TID stack walk had the same arbitrary memory read problem as the perf event stack walk. It would be nice if the kernel had a single stack walk implementation, but that's outside the scope of this commit. --- Kernel/Arch/x86/common/Processor.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Kernel/Arch/x86/common/Processor.cpp b/Kernel/Arch/x86/common/Processor.cpp index c0ca3f2145..d1a3576b7c 100644 --- a/Kernel/Arch/x86/common/Processor.cpp +++ b/Kernel/Arch/x86/common/Processor.cpp @@ -471,6 +471,7 @@ Vector Processor::capture_stack_trace(Thread& thread, size_t max_frames auto walk_stack = [&](FlatPtr stack_ptr) { static constexpr size_t max_stack_frames = 4096; + bool is_walking_userspace_stack = false; stack_trace.append(ip); size_t count = 1; while (stack_ptr && stack_trace.size() < max_stack_frames) { @@ -480,6 +481,15 @@ Vector Processor::capture_stack_trace(Thread& thread, size_t max_frames if (max_frames != 0 && count > max_frames) break; + if (!Memory::is_user_address(VirtualAddress { stack_ptr })) { + if (is_walking_userspace_stack) { + dbgln("SHENANIGANS! Userspace stack points back into kernel memory"); + break; + } + } else { + is_walking_userspace_stack = true; + } + if (Memory::is_user_range(VirtualAddress(stack_ptr), sizeof(FlatPtr) * 2)) { if (copy_from_user(&retaddr, &((FlatPtr*)stack_ptr)[1]).is_error() || !retaddr) break;