mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 18:17:44 +00:00
Implement sending signals to blocked-in-kernel processes.
This is dirty but pretty cool! If we have a pending, unmasked signal for a process that's blocked inside the kernel, we set up alternate stacks for that process and unblock it to execute the signal handler. A slightly different return trampoline is used here: since we need to get back into the kernel, a dedicated syscall is used (sys$sigreturn.) This restores the TSS contents of the process to the state it was in while we were originally blocking in the kernel. NOTE: There's currently only one "kernel resume TSS" so signal nesting definitely won't work.
This commit is contained in:
parent
c8b308910e
commit
03a8357e84
10 changed files with 190 additions and 27 deletions
|
@ -51,6 +51,13 @@ public:
|
|||
bool isRing0() const { return m_ring == Ring0; }
|
||||
bool isRing3() const { return m_ring == Ring3; }
|
||||
|
||||
bool is_blocked() const
|
||||
{
|
||||
return m_state == BlockedSleep || m_state == BlockedWait || m_state == BlockedRead;
|
||||
}
|
||||
|
||||
bool in_kernel() const { return (m_tss.cs & 0x03) == 0; }
|
||||
|
||||
static Process* fromPID(pid_t);
|
||||
static Process* kernelProcess();
|
||||
|
||||
|
@ -115,6 +122,7 @@ public:
|
|||
int sys$kill(pid_t pid, int sig);
|
||||
int sys$geterror() { return m_error; }
|
||||
void sys$exit(int status);
|
||||
void sys$sigreturn();
|
||||
pid_t sys$spawn(const char* path, const char** args, const char** envp);
|
||||
pid_t sys$waitpid(pid_t, int* wstatus, int options);
|
||||
void* sys$mmap(void*, size_t size);
|
||||
|
@ -212,6 +220,7 @@ private:
|
|||
State m_state { Invalid };
|
||||
DWORD m_wakeupTime { 0 };
|
||||
TSS32 m_tss;
|
||||
TSS32 m_tss_to_resume_kernel;
|
||||
Vector<RetainPtr<FileDescriptor>> m_file_descriptors;
|
||||
RingLevel m_ring { Ring0 };
|
||||
int m_error { 0 };
|
||||
|
@ -243,16 +252,23 @@ private:
|
|||
// FIXME: Implement some kind of ASLR?
|
||||
LinearAddress m_nextRegion;
|
||||
|
||||
LinearAddress m_return_from_signal_trampoline;
|
||||
LinearAddress m_return_to_ring3_from_signal_trampoline;
|
||||
LinearAddress m_return_to_ring0_from_signal_trampoline;
|
||||
|
||||
pid_t m_ppid { 0 };
|
||||
mode_t m_umask { 022 };
|
||||
|
||||
bool m_was_interrupted_while_blocked { false };
|
||||
|
||||
static void notify_waiters(pid_t waitee, int exit_status, int signal);
|
||||
|
||||
Vector<String> m_arguments;
|
||||
Vector<String> m_initialEnvironment;
|
||||
HashTable<gid_t> m_gids;
|
||||
|
||||
Region* m_stack_region { nullptr };
|
||||
Region* m_signal_stack_user_region { nullptr };
|
||||
Region* m_signal_stack_kernel_region { nullptr };
|
||||
};
|
||||
|
||||
class ProcessInspectionScope {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue