Kernel: Disable x86 RDTSC instruction in userspace
It's still possible to read the TSC via the read_tsc() syscall, but we will now clear some of the bottom bits for unprivileged users.
This commit is contained in:
parent
dfd759f75a
commit
38f93ef13b
Notes:
sideshowbarker
2024-07-19 10:28:41 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/38f93ef13b6
6 changed files with 25 additions and 1 deletions
|
@ -34,6 +34,7 @@ kinds of crashes.
|
||||||
* `-X`: Attempt to execute non-executable memory. (Not mapped with PROT\_EXEC.)
|
* `-X`: Attempt to execute non-executable memory. (Not mapped with PROT\_EXEC.)
|
||||||
* `-U`: Attempt to trigger an x86 User Mode Instruction Prevention fault.
|
* `-U`: Attempt to trigger an x86 User Mode Instruction Prevention fault.
|
||||||
* `-I`: Use an x86 I/O instruction in userspace.
|
* `-I`: Use an x86 I/O instruction in userspace.
|
||||||
|
* `-c`: Read the x86 TSC (Time Stamp Counter) directly.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|
|
@ -526,6 +526,7 @@ bool g_cpu_supports_pae;
|
||||||
bool g_cpu_supports_pge;
|
bool g_cpu_supports_pge;
|
||||||
bool g_cpu_supports_smep;
|
bool g_cpu_supports_smep;
|
||||||
bool g_cpu_supports_sse;
|
bool g_cpu_supports_sse;
|
||||||
|
bool g_cpu_supports_tsc;
|
||||||
bool g_cpu_supports_umip;
|
bool g_cpu_supports_umip;
|
||||||
|
|
||||||
void detect_cpu_features()
|
void detect_cpu_features()
|
||||||
|
@ -534,6 +535,7 @@ void detect_cpu_features()
|
||||||
g_cpu_supports_pae = (processor_info.edx() & (1 << 6));
|
g_cpu_supports_pae = (processor_info.edx() & (1 << 6));
|
||||||
g_cpu_supports_pge = (processor_info.edx() & (1 << 13));
|
g_cpu_supports_pge = (processor_info.edx() & (1 << 13));
|
||||||
g_cpu_supports_sse = (processor_info.edx() & (1 << 25));
|
g_cpu_supports_sse = (processor_info.edx() & (1 << 25));
|
||||||
|
g_cpu_supports_tsc = (processor_info.edx() & (1 << 4));
|
||||||
|
|
||||||
CPUID extended_processor_info(0x80000001);
|
CPUID extended_processor_info(0x80000001);
|
||||||
g_cpu_supports_nx = (extended_processor_info.edx() & (1 << 20));
|
g_cpu_supports_nx = (extended_processor_info.edx() & (1 << 20));
|
||||||
|
|
|
@ -513,4 +513,5 @@ extern bool g_cpu_supports_pae;
|
||||||
extern bool g_cpu_supports_pge;
|
extern bool g_cpu_supports_pge;
|
||||||
extern bool g_cpu_supports_smep;
|
extern bool g_cpu_supports_smep;
|
||||||
extern bool g_cpu_supports_sse;
|
extern bool g_cpu_supports_sse;
|
||||||
|
extern bool g_cpu_supports_tsc;
|
||||||
extern bool g_cpu_supports_umip;
|
extern bool g_cpu_supports_umip;
|
||||||
|
|
|
@ -2452,6 +2452,8 @@ int Process::sys$read_tsc(u32* lsw, u32* msw)
|
||||||
if (!validate_write_typed(msw))
|
if (!validate_write_typed(msw))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
read_tsc(*lsw, *msw);
|
read_tsc(*lsw, *msw);
|
||||||
|
if (!is_superuser())
|
||||||
|
*lsw &= ~0xfff;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -266,6 +266,14 @@ extern "C" [[noreturn]] void init(u32 physical_address_for_kernel_page_tables)
|
||||||
kprintf("x86: UMIP support enabled\n");
|
kprintf("x86: UMIP support enabled\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_cpu_supports_tsc) {
|
||||||
|
asm volatile(
|
||||||
|
"mov %cr4, %eax\n"
|
||||||
|
"orl $0x4, %eax\n"
|
||||||
|
"mov %eax, %cr4\n");
|
||||||
|
kprintf("x86: RDTSC support restricted\n");
|
||||||
|
}
|
||||||
|
|
||||||
RTC::initialize();
|
RTC::initialize();
|
||||||
PIC::initialize();
|
PIC::initialize();
|
||||||
gdt_init();
|
gdt_init();
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
static void print_usage_and_exit()
|
static void print_usage_and_exit()
|
||||||
{
|
{
|
||||||
printf("usage: crash -[AsdiamfMFTtSxyXUI]\n");
|
printf("usage: crash -[AsdiamfMFTtSxyXUIc]\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +101,7 @@ int main(int argc, char** argv)
|
||||||
ExecuteNonExecutableMemory,
|
ExecuteNonExecutableMemory,
|
||||||
TriggerUserModeInstructionPrevention,
|
TriggerUserModeInstructionPrevention,
|
||||||
UseIOInstruction,
|
UseIOInstruction,
|
||||||
|
ReadTimestampCounter,
|
||||||
};
|
};
|
||||||
Mode mode = SegmentationViolation;
|
Mode mode = SegmentationViolation;
|
||||||
|
|
||||||
|
@ -143,6 +144,8 @@ int main(int argc, char** argv)
|
||||||
mode = TriggerUserModeInstructionPrevention;
|
mode = TriggerUserModeInstructionPrevention;
|
||||||
else if (String(argv[1]) == "-I")
|
else if (String(argv[1]) == "-I")
|
||||||
mode = UseIOInstruction;
|
mode = UseIOInstruction;
|
||||||
|
else if (String(argv[1]) == "-c")
|
||||||
|
mode = ReadTimestampCounter;
|
||||||
else
|
else
|
||||||
print_usage_and_exit();
|
print_usage_and_exit();
|
||||||
|
|
||||||
|
@ -342,5 +345,12 @@ int main(int argc, char** argv)
|
||||||
}).run(run_type);
|
}).run(run_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mode == ReadTimestampCounter || mode == TestAllCrashTypes) {
|
||||||
|
Crash("Read the CPU timestamp counter", [] {
|
||||||
|
asm volatile("rdtsc");
|
||||||
|
return Crash::Failure::DidNotCrash;
|
||||||
|
}).run(run_type);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue