mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 23:58:11 +00:00
Kernel: Implement some basic stack pointer validation
VM regions can now be marked as stack regions, which is then validated on syscall, and on page fault. If a thread is caught with its stack pointer pointing into anything that's *not* a Region with its stack bit set, we'll crash the whole process with SIGSTKFLT. Userspace must now allocate custom stacks by using mmap() with the new MAP_STACK flag. This mechanism was first introduced in OpenBSD, and now we have it too, yay! :^)
This commit is contained in:
parent
197ed1bb2a
commit
794758df3a
12 changed files with 101 additions and 5 deletions
|
@ -5,7 +5,7 @@
|
|||
|
||||
static void print_usage_and_exit()
|
||||
{
|
||||
printf("usage: crash -[sdiamfMF]\n");
|
||||
printf("usage: crash -[sdiamfMFTt]\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@ int main(int argc, char** argv)
|
|||
ReadFromUninitializedMallocMemory,
|
||||
ReadFromFreedMemory,
|
||||
WriteToReadonlyMemory,
|
||||
InvalidStackPointerOnSyscall,
|
||||
InvalidStackPointerOnPageFault,
|
||||
};
|
||||
Mode mode = SegmentationViolation;
|
||||
|
||||
|
@ -46,6 +48,10 @@ int main(int argc, char** argv)
|
|||
mode = WriteToFreedMemory;
|
||||
else if (String(argv[1]) == "-r")
|
||||
mode = WriteToReadonlyMemory;
|
||||
else if (String(argv[1]) == "-T")
|
||||
mode = InvalidStackPointerOnSyscall;
|
||||
else if (String(argv[1]) == "-t")
|
||||
mode = InvalidStackPointerOnPageFault;
|
||||
else
|
||||
print_usage_and_exit();
|
||||
|
||||
|
@ -111,6 +117,41 @@ int main(int argc, char** argv)
|
|||
*ptr = 'y'; // This should crash!
|
||||
}
|
||||
|
||||
if (mode == InvalidStackPointerOnSyscall) {
|
||||
u8* makeshift_stack = (u8*)mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_STACK, 0, 0);
|
||||
if (!makeshift_stack) {
|
||||
perror("mmap");
|
||||
return 1;
|
||||
}
|
||||
u8* makeshift_esp = makeshift_stack + 2048;
|
||||
asm volatile("mov %%eax, %%esp" :: "a"(makeshift_esp));
|
||||
getuid();
|
||||
dbgprintf("Survived syscall with MAP_STACK stack\n");
|
||||
|
||||
u8* bad_stack = (u8*)mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
|
||||
if (!bad_stack) {
|
||||
perror("mmap");
|
||||
return 1;
|
||||
}
|
||||
u8* bad_esp = bad_stack + 2048;
|
||||
asm volatile("mov %%eax, %%esp" :: "a"(bad_esp));
|
||||
getuid();
|
||||
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
if (mode == InvalidStackPointerOnPageFault) {
|
||||
u8* bad_stack = (u8*)mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
|
||||
if (!bad_stack) {
|
||||
perror("mmap");
|
||||
return 1;
|
||||
}
|
||||
u8* bad_esp = bad_stack + 2048;
|
||||
asm volatile("mov %%eax, %%esp" :: "a"(bad_esp));
|
||||
asm volatile("pushl $0");
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
ASSERT_NOT_REACHED();
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue