diff --git a/Base/usr/share/man/man1/crash.md b/Base/usr/share/man/man1/crash.md index f85d681fb5bd66..94de627518f705 100644 --- a/Base/usr/share/man/man1/crash.md +++ b/Base/usr/share/man/man1/crash.md @@ -33,6 +33,7 @@ kinds of crashes. * `-y`: Write to recently freed memory. (Tests an opportunistic malloc guard.) * `-X`: Attempt to execute non-executable memory. (Not mapped with PROT\_EXEC.) * `-U`: Attempt to trigger an x86 User Mode Instruction Prevention fault. +* `-I`: Use an x86 I/O instruction in userspace. ## Examples diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 7954aa6f04c3d3..0dd13da90c1da0 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -705,6 +705,8 @@ int Process::do_exec(String path, Vector arguments, Vector envir new_main_thread->make_thread_specific_region({}); memset(&tss, 0, sizeof(TSS32)); + tss.iomapbase = sizeof(TSS32); + tss.eflags = 0x0202; tss.eip = entry_eip; tss.cs = 0x1b; diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp index 9f593ac297f480..1cbf9162e8a48d 100644 --- a/Kernel/Scheduler.cpp +++ b/Kernel/Scheduler.cpp @@ -476,10 +476,10 @@ bool Scheduler::context_switch(Thread& thread) thread.set_selector(gdt_alloc_entry()); auto& descriptor = get_gdt_entry(thread.selector()); descriptor.set_base(&thread.tss()); - descriptor.set_limit(0xffff); + descriptor.set_limit(sizeof(TSS32)); descriptor.dpl = 0; descriptor.segment_present = 1; - descriptor.granularity = 1; + descriptor.granularity = 0; descriptor.zero = 0; descriptor.operation_size = 1; descriptor.descriptor_type = 0; @@ -501,10 +501,10 @@ static void initialize_redirection() { auto& descriptor = get_gdt_entry(s_redirection.selector); descriptor.set_base(&s_redirection.tss); - descriptor.set_limit(0xffff); + descriptor.set_limit(sizeof(TSS32)); descriptor.dpl = 0; descriptor.segment_present = 1; - descriptor.granularity = 1; + descriptor.granularity = 0; descriptor.zero = 0; descriptor.operation_size = 1; descriptor.descriptor_type = 0; diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index 342a42878bb01a..ca906bba664aae 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -59,6 +59,7 @@ Thread::Thread(Process& process) m_fpu_state = (FPUState*)kmalloc_aligned(sizeof(FPUState), 16); memcpy(m_fpu_state, &s_clean_fpu_state, sizeof(FPUState)); memset(&m_tss, 0, sizeof(m_tss)); + m_tss.iomapbase = sizeof(TSS32); // Only IF is set when a process boots. m_tss.eflags = 0x0202; diff --git a/Userland/crash.cpp b/Userland/crash.cpp index 19faf069c7edb1..431d691ef391f8 100644 --- a/Userland/crash.cpp +++ b/Userland/crash.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -10,7 +11,7 @@ static void print_usage_and_exit() { - printf("usage: crash -[AsdiamfMFTtSxyXU]\n"); + printf("usage: crash -[AsdiamfMFTtSxyXUI]\n"); exit(0); } @@ -99,6 +100,7 @@ int main(int argc, char** argv) ReadFromFreedMemoryStillCachedByMalloc, ExecuteNonExecutableMemory, TriggerUserModeInstructionPrevention, + UseIOInstruction, }; Mode mode = SegmentationViolation; @@ -139,6 +141,8 @@ int main(int argc, char** argv) mode = ExecuteNonExecutableMemory; else if (String(argv[1]) == "-U") mode = TriggerUserModeInstructionPrevention; + else if (String(argv[1]) == "-I") + mode = UseIOInstruction; else print_usage_and_exit(); @@ -330,6 +334,13 @@ int main(int argc, char** argv) }).run(run_type); } + if (mode == UseIOInstruction || mode == TestAllCrashTypes) { + Crash("Attempt to use an I/O instruction", [] { + u8 keyboard_status = IO::in8(0x64); + printf("Keyboard status: %#02x\n", keyboard_status); + return Crash::Failure::DidNotCrash; + }).run(run_type); + } + return 0; } -