diff options
author | Andreas Kling <kling@serenityos.org> | 2021-02-08 23:01:53 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-02-08 23:05:41 +0100 |
commit | 4ff0f971f7e6898cbe890e0f368a27ed4d0d5344 (patch) | |
tree | f07152c1e4b6f4b66c754fe7d5feb4e0cef5f2f7 | |
parent | 4b7b92c20139f59b6b15efdb6dff0e716c7f3e76 (diff) | |
download | serenity-4ff0f971f7e6898cbe890e0f368a27ed4d0d5344.zip |
Kernel: Prevent execve/ptrace race
Add a per-process ptrace lock and use it to prevent ptrace access to a
process after it decides to commit to a new executable in sys$execve().
Fixes #5230.
-rw-r--r-- | Kernel/Process.h | 7 | ||||
-rw-r--r-- | Kernel/Syscalls/execve.cpp | 3 | ||||
-rw-r--r-- | Kernel/Syscalls/ptrace.cpp | 2 |
3 files changed, 8 insertions, 4 deletions
diff --git a/Kernel/Process.h b/Kernel/Process.h index 79bc2b0126..bc57a6c7c4 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -408,10 +408,8 @@ public: return m_thread_count.load(AK::MemoryOrder::memory_order_relaxed); } - Lock& big_lock() - { - return m_big_lock; - } + Lock& big_lock() { return m_big_lock; } + Lock& ptrace_lock() { return m_ptrace_lock; } Custody& root_directory(); Custody& root_directory_relative_to_global_root(); @@ -579,6 +577,7 @@ private: size_t m_master_tls_alignment { 0 }; Lock m_big_lock { "Process" }; + Lock m_ptrace_lock { "ptrace" }; RefPtr<Timer> m_alarm_timer; diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index 0c4f5bfa8d..0c74582bef 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -483,6 +483,9 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve // 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. + Locker ptrace_locker(ptrace_lock()); + // Disable profiling temporarily in case it's running on this process. TemporaryChange profiling_disabler(m_profiling, false); diff --git a/Kernel/Syscalls/ptrace.cpp b/Kernel/Syscalls/ptrace.cpp index b385f7d7ab..1382998279 100644 --- a/Kernel/Syscalls/ptrace.cpp +++ b/Kernel/Syscalls/ptrace.cpp @@ -57,6 +57,8 @@ static KResultOr<u32> handle_ptrace(const Kernel::Syscall::SC_ptrace_params& par if (!peer) return ESRCH; + Locker ptrace_locker(peer->process().ptrace_lock()); + if ((peer->process().uid() != caller.euid()) || (peer->process().uid() != peer->process().euid())) // Disallow tracing setuid processes return EACCES; |