diff --git a/Base/usr/share/man/man1/crash.md b/Base/usr/share/man/man1/crash.md index 8af17a8f07..174295c2a8 100644 --- a/Base/usr/share/man/man1/crash.md +++ b/Base/usr/share/man/man1/crash.md @@ -30,6 +30,7 @@ kinds of crashes. * `-S`: Make a syscall from writeable memory. * `-x`: Read from recently freed memory. (Tests an opportunistic malloc guard.) * `-y`: Write to recently freed memory. (Tests an opportunistic malloc guard.) +* `-X`: Attempt to execute non-executable memory. (Not mapped with PROT\_EXEC.) ## Examples diff --git a/Userland/crash.cpp b/Userland/crash.cpp index 6b8a00e636..48445ae70e 100644 --- a/Userland/crash.cpp +++ b/Userland/crash.cpp @@ -6,7 +6,7 @@ static void print_usage_and_exit() { - printf("usage: crash -[sdiamfMFTt]\n"); + printf("usage: crash -[sdiamfMFTtSxyX]\n"); exit(0); } @@ -28,6 +28,7 @@ int main(int argc, char** argv) SyscallFromWritableMemory, WriteToFreedMemoryStillCachedByMalloc, ReadFromFreedMemoryStillCachedByMalloc, + ExecuteNonExecutableMemory, }; Mode mode = SegmentationViolation; @@ -62,6 +63,8 @@ int main(int argc, char** argv) mode = ReadFromFreedMemoryStillCachedByMalloc; else if (String(argv[1]) == "-y") mode = WriteToFreedMemoryStillCachedByMalloc; + else if (String(argv[1]) == "-X") + mode = ExecuteNonExecutableMemory; else print_usage_and_exit(); @@ -184,6 +187,18 @@ int main(int argc, char** argv) ASSERT_NOT_REACHED(); } + if (mode == ExecuteNonExecutableMemory) { + auto* ptr = (u8*)mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); + ASSERT(ptr != MAP_FAILED); + + ptr[0] = 0xc3; // ret + + typedef void* (*CrashyFunctionPtr)(); + ((CrashyFunctionPtr)ptr)(); + + ASSERT_NOT_REACHED(); + } + ASSERT_NOT_REACHED(); return 0; }