1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 07:58:11 +00:00

Kernel: Prevent executing I/O instructions in userspace

All threads were running with iomapbase=0 in their TSS, which the CPU
interprets as "there's an I/O permission bitmap starting at offset 0
into my TSS".

Because of that, any bits that were 1 inside the TSS would allow the
thread to execute I/O instructions on the port with that bit index.

Fix this by always setting the iomapbase to sizeof(TSS32), and also
setting the TSS descriptor's limit to sizeof(TSS32), effectively making
the I/O permissions bitmap zero-length.

This should make it no longer possible to do I/O from userspace. :^)
This commit is contained in:
Andreas Kling 2020-01-01 17:26:25 +01:00
parent 37329c2009
commit f598bbbb1d
5 changed files with 21 additions and 6 deletions

View file

@ -1,5 +1,6 @@
#include <AK/Function.h>
#include <AK/String.h>
#include <Kernel/IO.h>
#include <Kernel/Syscall.h>
#include <stdio.h>
#include <stdlib.h>
@ -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;
}