mirror of
https://github.com/RGBCube/serenity
synced 2025-07-23 08:27:35 +00:00
Kernel: Stop perf event stack walk on bogus userspace->kernel traversal
When walking the stack to generate a perf_event sample, we now check if a userspace stack frame points back into kernel memory. It was possible to use this as an arbitrary kernel memory read. :^)
This commit is contained in:
parent
d82c91ac2c
commit
8ef9b003ad
1 changed files with 11 additions and 0 deletions
|
@ -43,10 +43,21 @@ static Vector<FlatPtr, PerformanceEvent::max_stack_frame_count> raw_backtrace(Fl
|
||||||
FlatPtr stack_ptr = bp;
|
FlatPtr stack_ptr = bp;
|
||||||
// FIXME: Figure out how to remove this SmapDisabler without breaking profile stacks.
|
// FIXME: Figure out how to remove this SmapDisabler without breaking profile stacks.
|
||||||
SmapDisabler disabler;
|
SmapDisabler disabler;
|
||||||
|
// NOTE: The stack should always have kernel frames first, followed by userspace frames.
|
||||||
|
// If a userspace frame points back into kernel memory, something is afoot.
|
||||||
|
bool is_walking_userspace_stack = false;
|
||||||
while (stack_ptr) {
|
while (stack_ptr) {
|
||||||
void* fault_at;
|
void* fault_at;
|
||||||
if (!safe_memcpy(&stack_ptr_copy, (void*)stack_ptr, sizeof(FlatPtr), fault_at))
|
if (!safe_memcpy(&stack_ptr_copy, (void*)stack_ptr, sizeof(FlatPtr), fault_at))
|
||||||
break;
|
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;
|
||||||
|
}
|
||||||
FlatPtr retaddr;
|
FlatPtr retaddr;
|
||||||
if (!safe_memcpy(&retaddr, (void*)(stack_ptr + sizeof(FlatPtr)), sizeof(FlatPtr), fault_at))
|
if (!safe_memcpy(&retaddr, (void*)(stack_ptr + sizeof(FlatPtr)), sizeof(FlatPtr), fault_at))
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue