diff --git a/Kernel/API/Syscall.h b/Kernel/API/Syscall.h index e83a67b5a35..1567de7fc9a 100644 --- a/Kernel/API/Syscall.h +++ b/Kernel/API/Syscall.h @@ -196,7 +196,8 @@ namespace Kernel { S(adjtime) \ S(allocate_tls) \ S(prctl) \ - S(mremap) + S(mremap) \ + S(set_coredump_metadata) namespace Syscall { @@ -442,6 +443,11 @@ struct SC_ptrace_peek_params { u32* out_data; }; +struct SC_set_coredump_metadata_params { + StringArgument key; + StringArgument value; +}; + void initialize(); int sync(); diff --git a/Kernel/Process.h b/Kernel/Process.h index b014dbc4a43..d859dfd7456 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -363,6 +363,7 @@ public: int sys$disown(ProcessID); void* sys$allocate_tls(size_t); int sys$prctl(int option, FlatPtr arg1, FlatPtr arg2); + int sys$set_coredump_metadata(Userspace); template int get_sock_or_peer_name(const Params&); @@ -500,6 +501,8 @@ public: void unblock_waiters(Thread::WaitBlocker::UnblockFlags, u8 signal = 0); Thread::WaitBlockCondition& wait_block_condition() { return m_wait_block_condition; } + const HashMap& coredump_metadata() const { return m_coredump_metadata; } + private: friend class MemoryManager; friend class Scheduler; @@ -644,6 +647,8 @@ private: bool m_wait_for_tracer_at_next_execve { false }; Thread::WaitBlockCondition m_wait_block_condition; + + HashMap m_coredump_metadata; }; extern InlineLinkedList* g_processes; diff --git a/Kernel/Syscalls/process.cpp b/Kernel/Syscalls/process.cpp index bc90a38d560..a10b506f342 100644 --- a/Kernel/Syscalls/process.cpp +++ b/Kernel/Syscalls/process.cpp @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include @@ -64,4 +65,25 @@ int Process::sys$set_process_name(Userspace user_name, size_t user_ return 0; } +int Process::sys$set_coredump_metadata(Userspace user_params) +{ + Syscall::SC_set_coredump_metadata_params params; + if (!copy_from_user(¶ms, user_params)) + return -EFAULT; + if (params.key.length == 0 || params.key.length > 16 * KiB) + return -EINVAL; + if (params.value.length > 16 * KiB) + return -EINVAL; + auto copied_key = copy_string_from_user(params.key.characters, params.key.length); + if (copied_key.is_null()) + return -EFAULT; + auto copied_value = copy_string_from_user(params.value.characters, params.value.length); + if (copied_value.is_null()) + return -EFAULT; + if (!m_coredump_metadata.contains(copied_key) && m_coredump_metadata.size() >= 16) + return -EFAULT; + m_coredump_metadata.set(move(copied_key), move(copied_value)); + return 0; +} + }