mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 21:57:43 +00:00
Kernel: Map signal trampoline into each process's address space
The signal trampoline was previously in kernelspace memory, but with a special exception to make it user-accessible. This patch moves it into each process's regular address space so we can stop supporting user-allowed memory above 0xc0000000.
This commit is contained in:
parent
3551198f99
commit
1593219a41
4 changed files with 30 additions and 17 deletions
|
@ -58,15 +58,15 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
static void create_signal_trampolines();
|
static void create_signal_trampoline();
|
||||||
|
|
||||||
RecursiveSpinLock g_processes_lock;
|
RecursiveSpinLock g_processes_lock;
|
||||||
static Atomic<pid_t> next_pid;
|
static Atomic<pid_t> next_pid;
|
||||||
InlineLinkedList<Process>* g_processes;
|
InlineLinkedList<Process>* g_processes;
|
||||||
String* g_hostname;
|
String* g_hostname;
|
||||||
Lock* g_hostname_lock;
|
Lock* g_hostname_lock;
|
||||||
VirtualAddress g_return_to_ring3_from_signal_trampoline;
|
|
||||||
HashMap<String, OwnPtr<Module>>* g_modules;
|
HashMap<String, OwnPtr<Module>>* g_modules;
|
||||||
|
Region* g_signal_trampoline_region;
|
||||||
|
|
||||||
ProcessID Process::allocate_pid()
|
ProcessID Process::allocate_pid()
|
||||||
{
|
{
|
||||||
|
@ -88,7 +88,7 @@ void Process::initialize()
|
||||||
g_hostname = new String("courage");
|
g_hostname = new String("courage");
|
||||||
g_hostname_lock = new Lock;
|
g_hostname_lock = new Lock;
|
||||||
|
|
||||||
create_signal_trampolines();
|
create_signal_trampoline();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<ProcessID> Process::all_pids()
|
Vector<ProcessID> Process::all_pids()
|
||||||
|
@ -285,25 +285,21 @@ void signal_trampoline_dummy()
|
||||||
extern "C" void asm_signal_trampoline(void);
|
extern "C" void asm_signal_trampoline(void);
|
||||||
extern "C" void asm_signal_trampoline_end(void);
|
extern "C" void asm_signal_trampoline_end(void);
|
||||||
|
|
||||||
void create_signal_trampolines()
|
void create_signal_trampoline()
|
||||||
{
|
{
|
||||||
// NOTE: We leak this region.
|
// NOTE: We leak this region.
|
||||||
auto* trampoline_region = MM.allocate_user_accessible_kernel_region(PAGE_SIZE, "Signal trampolines", Region::Access::Read | Region::Access::Write | Region::Access::Execute, false).leak_ptr();
|
g_signal_trampoline_region = MM.allocate_kernel_region(PAGE_SIZE, "Signal trampolines", Region::Access::Read | Region::Access::Write, false).leak_ptr();
|
||||||
trampoline_region->set_syscall_region(true);
|
g_signal_trampoline_region->set_syscall_region(true);
|
||||||
g_return_to_ring3_from_signal_trampoline = trampoline_region->vaddr();
|
|
||||||
|
|
||||||
u8* trampoline = (u8*)asm_signal_trampoline;
|
u8* trampoline = (u8*)asm_signal_trampoline;
|
||||||
u8* trampoline_end = (u8*)asm_signal_trampoline_end;
|
u8* trampoline_end = (u8*)asm_signal_trampoline_end;
|
||||||
size_t trampoline_size = trampoline_end - trampoline;
|
size_t trampoline_size = trampoline_end - trampoline;
|
||||||
|
|
||||||
{
|
u8* code_ptr = (u8*)g_signal_trampoline_region->vaddr().as_ptr();
|
||||||
SmapDisabler disabler;
|
memcpy(code_ptr, trampoline, trampoline_size);
|
||||||
u8* code_ptr = (u8*)trampoline_region->vaddr().as_ptr();
|
|
||||||
memcpy(code_ptr, trampoline, trampoline_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
trampoline_region->set_writable(false);
|
g_signal_trampoline_region->set_writable(false);
|
||||||
trampoline_region->remap();
|
g_signal_trampoline_region->remap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process::crash(int signal, u32 eip, bool out_of_memory)
|
void Process::crash(int signal, u32 eip, bool out_of_memory)
|
||||||
|
|
|
@ -57,8 +57,6 @@ namespace Kernel {
|
||||||
timeval kgettimeofday();
|
timeval kgettimeofday();
|
||||||
void kgettimeofday(timeval&);
|
void kgettimeofday(timeval&);
|
||||||
|
|
||||||
extern VirtualAddress g_return_to_ring3_from_signal_trampoline;
|
|
||||||
|
|
||||||
#define ENUMERATE_PLEDGE_PROMISES \
|
#define ENUMERATE_PLEDGE_PROMISES \
|
||||||
__ENUMERATE_PLEDGE_PROMISE(stdio) \
|
__ENUMERATE_PLEDGE_PROMISE(stdio) \
|
||||||
__ENUMERATE_PLEDGE_PROMISE(rpath) \
|
__ENUMERATE_PLEDGE_PROMISE(rpath) \
|
||||||
|
@ -458,6 +456,8 @@ public:
|
||||||
Space& space() { return *m_space; }
|
Space& space() { return *m_space; }
|
||||||
const Space& space() const { return *m_space; }
|
const Space& space() const { return *m_space; }
|
||||||
|
|
||||||
|
VirtualAddress signal_trampoline() const { return m_signal_trampoline; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class MemoryManager;
|
friend class MemoryManager;
|
||||||
friend class Scheduler;
|
friend class Scheduler;
|
||||||
|
@ -507,6 +507,7 @@ private:
|
||||||
String m_name;
|
String m_name;
|
||||||
|
|
||||||
OwnPtr<Space> m_space;
|
OwnPtr<Space> m_space;
|
||||||
|
VirtualAddress m_signal_trampoline;
|
||||||
|
|
||||||
ProcessID m_pid { 0 };
|
ProcessID m_pid { 0 };
|
||||||
SessionID m_sid { 0 };
|
SessionID m_sid { 0 };
|
||||||
|
|
|
@ -47,6 +47,8 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
extern Region* g_signal_trampoline_region;
|
||||||
|
|
||||||
struct LoadResult {
|
struct LoadResult {
|
||||||
OwnPtr<Space> space;
|
OwnPtr<Space> space;
|
||||||
FlatPtr load_base { 0 };
|
FlatPtr load_base { 0 };
|
||||||
|
@ -481,6 +483,12 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve
|
||||||
return load_result_or_error.error();
|
return load_result_or_error.error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto signal_trampoline_range = load_result_or_error.value().space->allocate_range({}, PAGE_SIZE);
|
||||||
|
if (!signal_trampoline_range.has_value()) {
|
||||||
|
dbgln("do_exec: Failed to allocate VM for signal trampoline");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
// We commit to the new executable at this point. There is no turning back!
|
// We commit to the new executable at this point. There is no turning back!
|
||||||
|
|
||||||
// Prevent other processes from attaching to us with ptrace while we're doing this.
|
// Prevent other processes from attaching to us with ptrace while we're doing this.
|
||||||
|
@ -510,6 +518,14 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve
|
||||||
m_space = load_result.space.release_nonnull();
|
m_space = load_result.space.release_nonnull();
|
||||||
MemoryManager::enter_space(*m_space);
|
MemoryManager::enter_space(*m_space);
|
||||||
|
|
||||||
|
auto signal_trampoline_region = m_space->allocate_region_with_vmobject(signal_trampoline_range.value(), g_signal_trampoline_region->vmobject(), 0, "Signal trampoline", PROT_READ | PROT_EXEC, true);
|
||||||
|
if (signal_trampoline_region.is_error()) {
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
signal_trampoline_region.value()->set_syscall_region(true);
|
||||||
|
m_signal_trampoline = signal_trampoline_region.value()->vaddr();
|
||||||
|
|
||||||
m_executable = main_program_description->custody();
|
m_executable = main_program_description->custody();
|
||||||
m_arguments = arguments;
|
m_arguments = arguments;
|
||||||
m_environment = environment;
|
m_environment = environment;
|
||||||
|
|
|
@ -834,7 +834,7 @@ DispatchSignalResult Thread::dispatch_signal(u8 signal)
|
||||||
// valid (fork, exec etc) but the tss will, so we use that instead.
|
// valid (fork, exec etc) but the tss will, so we use that instead.
|
||||||
auto& regs = get_register_dump_from_stack();
|
auto& regs = get_register_dump_from_stack();
|
||||||
setup_stack(regs);
|
setup_stack(regs);
|
||||||
regs.eip = g_return_to_ring3_from_signal_trampoline.get();
|
regs.eip = process.signal_trampoline().get();
|
||||||
|
|
||||||
#if SIGNAL_DEBUG
|
#if SIGNAL_DEBUG
|
||||||
dbgln("signal: Thread in state '{}' has been primed with signal handler {:04x}:{:08x} to deliver {}", state_string(), m_tss.cs, m_tss.eip, signal);
|
dbgln("signal: Thread in state '{}' has been primed with signal handler {:04x}:{:08x} to deliver {}", state_string(), m_tss.cs, m_tss.eip, signal);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue