From ddab7ab6933cdcef5ca170007d3803cb9de09765 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 6 Aug 2020 11:17:53 +0200 Subject: [PATCH] Kernel: Store TTY's foreground process as a WeakPtr This ensures that we don't leave a stale PGID assigned to the TTY after the process exits, which would make PID recycling attacks possible. --- Kernel/Process.h | 10 ++++++++-- Kernel/TTY/TTY.cpp | 16 +++++++++++----- Kernel/TTY/TTY.h | 8 +++----- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/Kernel/Process.h b/Kernel/Process.h index abf213aa06..e27adc9d5d 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -106,7 +107,11 @@ struct UnveiledPath { unsigned permissions { 0 }; }; -class Process : public RefCounted, public InlineLinkedListNode { +class Process + : public RefCounted + , public InlineLinkedListNode + , public Weakable { + AK_MAKE_NONCOPYABLE(Process); AK_MAKE_NONMOVABLE(Process); @@ -453,7 +458,8 @@ public: [[nodiscard]] String validate_and_copy_string_from_user(Userspace user_characters, size_t size) const { - return validate_and_copy_string_from_user(user_characters.unsafe_userspace_ptr(), size); } + return validate_and_copy_string_from_user(user_characters.unsafe_userspace_ptr(), size); + } [[nodiscard]] String validate_and_copy_string_from_user(const Syscall::StringArgument&) const; diff --git a/Kernel/TTY/TTY.cpp b/Kernel/TTY/TTY.cpp index bc9ff14ff3..e3b655d24f 100644 --- a/Kernel/TTY/TTY.cpp +++ b/Kernel/TTY/TTY.cpp @@ -155,9 +155,9 @@ void TTY::emit(u8 ch) if (ch == m_termios.c_cc[VSUSP]) { dbg() << tty_name() << ": VSUSP pressed!"; generate_signal(SIGTSTP); - if (auto process = Process::from_pid(m_pgid)) { - if (auto parent = Process::from_pid(process->ppid())) - (void)parent->send_signal(SIGCHLD, process); + if (m_process) { + if (auto parent = Process::from_pid(m_process->ppid())) + (void)parent->send_signal(SIGCHLD, m_process); } return; } @@ -304,7 +304,7 @@ int TTY::ioctl(FileDescription&, unsigned request, FlatPtr arg) #endif switch (request) { case TIOCGPGRP: - return m_pgid; + return this->pgid(); case TIOCSPGRP: pgid = static_cast(arg); if (pgid <= 0) @@ -318,8 +318,8 @@ int TTY::ioctl(FileDescription&, unsigned request, FlatPtr arg) return -EPERM; if (current_process.sid() != process->sid()) return -EPERM; + m_process = process->make_weak_ptr(); } - m_pgid = pgid; return 0; case TCGETS: { user_termios = reinterpret_cast(arg); @@ -394,4 +394,10 @@ void TTY::hang_up() { generate_signal(SIGHUP); } + +pid_t TTY::pgid() const +{ + return m_process ? m_process->pgid() : 0; +} + } diff --git a/Kernel/TTY/TTY.h b/Kernel/TTY/TTY.h index 7644a5318a..cbaf23e9e6 100644 --- a/Kernel/TTY/TTY.h +++ b/Kernel/TTY/TTY.h @@ -27,14 +27,13 @@ #pragma once #include +#include #include #include #include namespace Kernel { -class Process; - class TTY : public CharacterDevice { public: virtual ~TTY() override; @@ -51,8 +50,7 @@ public: unsigned short rows() const { return m_rows; } unsigned short columns() const { return m_columns; } - void set_pgid(pid_t pgid) { m_pgid = pgid; } - pid_t pgid() const { return m_pgid; } + pid_t pgid() const; void set_termios(const termios&); bool should_generate_signals() const { return m_termios.c_lflag & ISIG; } @@ -93,7 +91,7 @@ private: virtual bool is_tty() const final override { return true; } CircularDeque m_input_buffer; - pid_t m_pgid { 0 }; + WeakPtr m_process; termios m_termios; unsigned short m_rows { 0 }; unsigned short m_columns { 0 };