mirror of
https://github.com/RGBCube/serenity
synced 2025-05-26 01:55:08 +00:00
Kernel: Start implementing x86 SMAP support
Supervisor Mode Access Prevention (SMAP) is an x86 CPU feature that prevents the kernel from accessing userspace memory. With SMAP enabled, trying to read/write a userspace memory address while in the kernel will now generate a page fault. Since it's sometimes necessary to read/write userspace memory, there are two new instructions that quickly switch the protection on/off: STAC (disables protection) and CLAC (enables protection.) These are exposed in kernel code via the stac() and clac() helpers. There's also a SmapDisabler RAII object that can be used to ensure that you don't forget to re-enable protection before returning to userspace code. THis patch also adds copy_to_user(), copy_from_user() and memset_user() which are the "correct" way of doing things. These functions allow us to briefly disable protection for a specific purpose, and then turn it back on immediately after it's done. Going forward all kernel code should be moved to using these and all uses of SmapDisabler are to be considered FIXME's. Note that we're not realizing the full potential of this feature since I've used SmapDisabler quite liberally in this initial bring-up patch.
This commit is contained in:
parent
04b734501a
commit
9eef39d68a
11 changed files with 245 additions and 60 deletions
|
@ -1,5 +1,6 @@
|
|||
#include <AK/Demangle.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <Kernel/Arch/i386/CPU.h>
|
||||
#include <Kernel/FileSystem/FileDescription.h>
|
||||
#include <Kernel/Process.h>
|
||||
#include <Kernel/Scheduler.h>
|
||||
|
@ -582,7 +583,7 @@ void Thread::push_value_on_stack(u32 value)
|
|||
{
|
||||
m_tss.esp -= 4;
|
||||
u32* stack_ptr = (u32*)m_tss.esp;
|
||||
*stack_ptr = value;
|
||||
copy_to_user(stack_ptr, &value, sizeof(value));
|
||||
}
|
||||
|
||||
RegisterDump& Thread::get_register_dump_from_stack()
|
||||
|
@ -609,6 +610,8 @@ u32 Thread::make_userspace_stack_for_main_thread(Vector<String> arguments, Vecto
|
|||
char** env = argv + arguments.size() + 1;
|
||||
char* bufptr = stack_base + (sizeof(char*) * (arguments.size() + 1)) + (sizeof(char*) * (environment.size() + 1));
|
||||
|
||||
SmapDisabler disabler;
|
||||
|
||||
for (int i = 0; i < arguments.size(); ++i) {
|
||||
argv[i] = bufptr;
|
||||
memcpy(bufptr, arguments[i].characters(), arguments[i].length());
|
||||
|
@ -700,6 +703,7 @@ String Thread::backtrace(ProcessInspectionHandle&) const
|
|||
|
||||
String Thread::backtrace_impl() const
|
||||
{
|
||||
SmapDisabler disabler;
|
||||
auto& process = const_cast<Process&>(this->process());
|
||||
ProcessPagingScope paging_scope(process);
|
||||
struct RecognizedSymbol {
|
||||
|
@ -757,6 +761,7 @@ void Thread::make_thread_specific_region(Badge<Process>)
|
|||
size_t thread_specific_region_alignment = max(process().m_master_tls_alignment, alignof(ThreadSpecificData));
|
||||
size_t thread_specific_region_size = align_up_to(process().m_master_tls_size, thread_specific_region_alignment) + sizeof(ThreadSpecificData);
|
||||
auto* region = process().allocate_region({}, thread_specific_region_size, "Thread-specific", PROT_READ | PROT_WRITE, true);
|
||||
SmapDisabler disabler;
|
||||
auto* thread_specific_data = (ThreadSpecificData*)region->vaddr().offset(align_up_to(process().m_master_tls_size, thread_specific_region_alignment)).as_ptr();
|
||||
auto* thread_local_storage = (u8*)((u8*)thread_specific_data) - align_up_to(process().m_master_tls_size, process().m_master_tls_alignment);
|
||||
m_thread_specific_data = VirtualAddress((u32)thread_specific_data);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue