summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-02-08 23:01:53 +0100
committerAndreas Kling <kling@serenityos.org>2021-02-08 23:05:41 +0100
commit4ff0f971f7e6898cbe890e0f368a27ed4d0d5344 (patch)
treef07152c1e4b6f4b66c754fe7d5feb4e0cef5f2f7
parent4b7b92c20139f59b6b15efdb6dff0e716c7f3e76 (diff)
downloadserenity-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.h7
-rw-r--r--Kernel/Syscalls/execve.cpp3
-rw-r--r--Kernel/Syscalls/ptrace.cpp2
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;