Serenity Operating System
at master 1031 lines 44 kB view raw
1/* 2 * Copyright (c) 2018-2022, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/Concepts.h> 10#include <AK/HashMap.h> 11#include <AK/IntrusiveList.h> 12#include <AK/IntrusiveListRelaxedConst.h> 13#include <AK/OwnPtr.h> 14#include <AK/RefPtr.h> 15#include <AK/Userspace.h> 16#include <AK/Variant.h> 17#include <Kernel/API/POSIX/select.h> 18#include <Kernel/API/POSIX/sys/resource.h> 19#include <Kernel/API/Syscall.h> 20#include <Kernel/Assertions.h> 21#include <Kernel/AtomicEdgeAction.h> 22#include <Kernel/Credentials.h> 23#include <Kernel/FileSystem/InodeMetadata.h> 24#include <Kernel/FileSystem/OpenFileDescription.h> 25#include <Kernel/FileSystem/UnveilNode.h> 26#include <Kernel/Forward.h> 27#include <Kernel/FutexQueue.h> 28#include <Kernel/Jail.h> 29#include <Kernel/Library/LockWeakPtr.h> 30#include <Kernel/Library/LockWeakable.h> 31#include <Kernel/Locking/Mutex.h> 32#include <Kernel/Locking/MutexProtected.h> 33#include <Kernel/Memory/AddressSpace.h> 34#include <Kernel/PerformanceEventBuffer.h> 35#include <Kernel/ProcessGroup.h> 36#include <Kernel/StdLib.h> 37#include <Kernel/Thread.h> 38#include <Kernel/UnixTypes.h> 39#include <LibC/elf.h> 40 41namespace Kernel { 42 43MutexProtected<OwnPtr<KString>>& hostname(); 44Time kgettimeofday(); 45 46#define ENUMERATE_PLEDGE_PROMISES \ 47 __ENUMERATE_PLEDGE_PROMISE(stdio) \ 48 __ENUMERATE_PLEDGE_PROMISE(rpath) \ 49 __ENUMERATE_PLEDGE_PROMISE(wpath) \ 50 __ENUMERATE_PLEDGE_PROMISE(cpath) \ 51 __ENUMERATE_PLEDGE_PROMISE(dpath) \ 52 __ENUMERATE_PLEDGE_PROMISE(inet) \ 53 __ENUMERATE_PLEDGE_PROMISE(id) \ 54 __ENUMERATE_PLEDGE_PROMISE(proc) \ 55 __ENUMERATE_PLEDGE_PROMISE(ptrace) \ 56 __ENUMERATE_PLEDGE_PROMISE(exec) \ 57 __ENUMERATE_PLEDGE_PROMISE(unix) \ 58 __ENUMERATE_PLEDGE_PROMISE(recvfd) \ 59 __ENUMERATE_PLEDGE_PROMISE(sendfd) \ 60 __ENUMERATE_PLEDGE_PROMISE(fattr) \ 61 __ENUMERATE_PLEDGE_PROMISE(tty) \ 62 __ENUMERATE_PLEDGE_PROMISE(chown) \ 63 __ENUMERATE_PLEDGE_PROMISE(thread) \ 64 __ENUMERATE_PLEDGE_PROMISE(video) \ 65 __ENUMERATE_PLEDGE_PROMISE(accept) \ 66 __ENUMERATE_PLEDGE_PROMISE(settime) \ 67 __ENUMERATE_PLEDGE_PROMISE(sigaction) \ 68 __ENUMERATE_PLEDGE_PROMISE(setkeymap) \ 69 __ENUMERATE_PLEDGE_PROMISE(prot_exec) \ 70 __ENUMERATE_PLEDGE_PROMISE(map_fixed) \ 71 __ENUMERATE_PLEDGE_PROMISE(getkeymap) \ 72 __ENUMERATE_PLEDGE_PROMISE(jail) \ 73 __ENUMERATE_PLEDGE_PROMISE(no_error) 74 75enum class Pledge : u32 { 76#define __ENUMERATE_PLEDGE_PROMISE(x) x, 77 ENUMERATE_PLEDGE_PROMISES 78#undef __ENUMERATE_PLEDGE_PROMISE 79}; 80 81enum class VeilState { 82 None, 83 Dropped, 84 Locked, 85 LockedInherited, 86}; 87 88static constexpr FlatPtr futex_key_private_flag = 0b1; 89union GlobalFutexKey { 90 struct { 91 Memory::VMObject const* vmobject; 92 FlatPtr offset; 93 } shared; 94 struct { 95 Memory::AddressSpace const* address_space; 96 FlatPtr user_address; 97 } private_; 98 struct { 99 FlatPtr parent; 100 FlatPtr offset; 101 } raw; 102}; 103static_assert(sizeof(GlobalFutexKey) == (sizeof(FlatPtr) * 2)); 104 105struct LoadResult; 106 107class ProcessList; 108 109class Process final 110 : public ListedRefCounted<Process, LockType::Spinlock> 111 , public LockWeakable<Process> { 112 113 class ProtectedValues { 114 public: 115 ProcessID pid { 0 }; 116 ProcessID ppid { 0 }; 117 SessionID sid { 0 }; 118 // FIXME: This should be a NonnullRefPtr 119 RefPtr<Credentials> credentials; 120 bool dumpable { false }; 121 bool executable_is_setid { false }; 122 Atomic<bool> has_promises { false }; 123 Atomic<u32> promises { 0 }; 124 Atomic<bool> has_execpromises { false }; 125 Atomic<u32> execpromises { 0 }; 126 mode_t umask { 022 }; 127 VirtualAddress signal_trampoline; 128 Atomic<u32> thread_count { 0 }; 129 u8 termination_status { 0 }; 130 u8 termination_signal { 0 }; 131 }; 132 133public: 134 AK_MAKE_NONCOPYABLE(Process); 135 AK_MAKE_NONMOVABLE(Process); 136 137 MAKE_ALIGNED_ALLOCATED(Process, PAGE_SIZE); 138 139 friend class Thread; 140 friend class Coredump; 141 142 auto with_protected_data(auto&& callback) const 143 { 144 SpinlockLocker locker(m_protected_data_lock); 145 return callback(m_protected_values_do_not_access_directly); 146 } 147 148 auto with_mutable_protected_data(auto&& callback) 149 { 150 SpinlockLocker locker(m_protected_data_lock); 151 unprotect_data(); 152 auto guard = ScopeGuard([&] { protect_data(); }); 153 return callback(m_protected_values_do_not_access_directly); 154 } 155 156 enum class State : u8 { 157 Running = 0, 158 Dying, 159 Dead 160 }; 161 162public: 163 static Process& current() 164 { 165 auto* current_thread = Processor::current_thread(); 166 VERIFY(current_thread); 167 return current_thread->process(); 168 } 169 170 static bool has_current() 171 { 172 return Processor::current_thread() != nullptr; 173 } 174 175 template<typename EntryFunction> 176 static void kernel_process_trampoline(void* data) 177 { 178 EntryFunction* func = reinterpret_cast<EntryFunction*>(data); 179 (*func)(); 180 delete func; 181 } 182 183 enum class RegisterProcess { 184 No, 185 Yes 186 }; 187 188 template<typename EntryFunction> 189 static LockRefPtr<Process> create_kernel_process(LockRefPtr<Thread>& first_thread, NonnullOwnPtr<KString> name, EntryFunction entry, u32 affinity = THREAD_AFFINITY_DEFAULT, RegisterProcess do_register = RegisterProcess::Yes) 190 { 191 auto* entry_func = new EntryFunction(move(entry)); 192 return create_kernel_process(first_thread, move(name), &Process::kernel_process_trampoline<EntryFunction>, entry_func, affinity, do_register); 193 } 194 195 static LockRefPtr<Process> create_kernel_process(LockRefPtr<Thread>& first_thread, NonnullOwnPtr<KString> name, void (*entry)(void*), void* entry_data = nullptr, u32 affinity = THREAD_AFFINITY_DEFAULT, RegisterProcess do_register = RegisterProcess::Yes); 196 static ErrorOr<NonnullLockRefPtr<Process>> try_create_user_process(LockRefPtr<Thread>& first_thread, StringView path, UserID, GroupID, Vector<NonnullOwnPtr<KString>> arguments, Vector<NonnullOwnPtr<KString>> environment, TTY*); 197 static void register_new(Process&); 198 199 ~Process(); 200 201 LockRefPtr<Thread> create_kernel_thread(void (*entry)(void*), void* entry_data, u32 priority, NonnullOwnPtr<KString> name, u32 affinity = THREAD_AFFINITY_DEFAULT, bool joinable = true); 202 203 bool is_profiling() const { return m_profiling; } 204 void set_profiling(bool profiling) { m_profiling = profiling; } 205 206 bool should_generate_coredump() const { return m_should_generate_coredump; } 207 void set_should_generate_coredump(bool b) { m_should_generate_coredump = b; } 208 209 bool is_dying() const { return m_state.load(AK::MemoryOrder::memory_order_acquire) != State::Running; } 210 bool is_dead() const { return m_state.load(AK::MemoryOrder::memory_order_acquire) == State::Dead; } 211 212 bool is_stopped() const { return m_is_stopped; } 213 bool set_stopped(bool stopped) { return m_is_stopped.exchange(stopped); } 214 215 bool is_kernel_process() const { return m_is_kernel_process; } 216 bool is_user_process() const { return !m_is_kernel_process; } 217 218 static LockRefPtr<Process> from_pid_in_same_jail(ProcessID); 219 static LockRefPtr<Process> from_pid_ignoring_jails(ProcessID); 220 static SessionID get_sid_from_pgid(ProcessGroupID pgid); 221 222 SpinlockProtected<NonnullOwnPtr<KString>, LockRank::None> const& name() const; 223 void set_name(NonnullOwnPtr<KString>); 224 225 ProcessID pid() const 226 { 227 return with_protected_data([](auto& protected_data) { return protected_data.pid; }); 228 } 229 SessionID sid() const 230 { 231 return with_protected_data([](auto& protected_data) { return protected_data.sid; }); 232 } 233 bool is_session_leader() const { return sid().value() == pid().value(); } 234 ProcessGroupID pgid() const { return m_pg ? m_pg->pgid() : 0; } 235 bool is_group_leader() const { return pgid().value() == pid().value(); } 236 ProcessID ppid() const 237 { 238 return with_protected_data([](auto& protected_data) { return protected_data.ppid; }); 239 } 240 241 SpinlockProtected<RefPtr<Jail>, LockRank::Process> const& jail() { return m_attached_jail; } 242 243 bool is_currently_in_jail() const 244 { 245 return m_attached_jail.with([&](auto& jail) -> bool { return !jail.is_null(); }); 246 } 247 248 NonnullRefPtr<Credentials> credentials() const; 249 250 bool is_dumpable() const 251 { 252 return with_protected_data([](auto& protected_data) { return protected_data.dumpable; }); 253 } 254 255 mode_t umask() const 256 { 257 return with_protected_data([](auto& protected_data) { return protected_data.umask; }); 258 } 259 260 // Breakable iteration functions 261 template<IteratorFunction<Process&> Callback> 262 static void for_each_ignoring_jails(Callback); 263 264 static ErrorOr<void> for_each_in_same_jail(Function<ErrorOr<void>(Process&)>); 265 ErrorOr<void> for_each_in_pgrp_in_same_jail(ProcessGroupID, Function<ErrorOr<void>(Process&)>); 266 ErrorOr<void> for_each_child_in_same_jail(Function<ErrorOr<void>(Process&)>); 267 268 template<IteratorFunction<Thread&> Callback> 269 IterationDecision for_each_thread(Callback); 270 template<IteratorFunction<Thread&> Callback> 271 IterationDecision for_each_thread(Callback callback) const; 272 ErrorOr<void> try_for_each_thread(Function<ErrorOr<void>(Thread const&)>) const; 273 274 // Non-breakable iteration functions 275 template<VoidFunction<Process&> Callback> 276 static void for_each_ignoring_jails(Callback); 277 278 template<VoidFunction<Thread&> Callback> 279 IterationDecision for_each_thread(Callback); 280 template<VoidFunction<Thread&> Callback> 281 IterationDecision for_each_thread(Callback callback) const; 282 283 void die(); 284 void finalize(); 285 286 ThreadTracer* tracer() { return m_tracer.ptr(); } 287 bool is_traced() const { return !!m_tracer; } 288 ErrorOr<void> start_tracing_from(ProcessID tracer); 289 void stop_tracing(); 290 void tracer_trap(Thread&, RegisterState const&); 291 292 ErrorOr<FlatPtr> sys$emuctl(); 293 ErrorOr<FlatPtr> sys$yield(); 294 ErrorOr<FlatPtr> sys$sync(); 295 ErrorOr<FlatPtr> sys$beep(int tone); 296 ErrorOr<FlatPtr> sys$get_process_name(Userspace<char*> buffer, size_t buffer_size); 297 ErrorOr<FlatPtr> sys$set_process_name(Userspace<char const*> user_name, size_t user_name_length); 298 ErrorOr<FlatPtr> sys$create_inode_watcher(u32 flags); 299 ErrorOr<FlatPtr> sys$inode_watcher_add_watch(Userspace<Syscall::SC_inode_watcher_add_watch_params const*> user_params); 300 ErrorOr<FlatPtr> sys$inode_watcher_remove_watch(int fd, int wd); 301 ErrorOr<FlatPtr> sys$dbgputstr(Userspace<char const*>, size_t); 302 ErrorOr<FlatPtr> sys$dump_backtrace(); 303 ErrorOr<FlatPtr> sys$gettid(); 304 ErrorOr<FlatPtr> sys$setsid(); 305 ErrorOr<FlatPtr> sys$getsid(pid_t); 306 ErrorOr<FlatPtr> sys$setpgid(pid_t pid, pid_t pgid); 307 ErrorOr<FlatPtr> sys$getpgrp(); 308 ErrorOr<FlatPtr> sys$getpgid(pid_t); 309 ErrorOr<FlatPtr> sys$getuid(); 310 ErrorOr<FlatPtr> sys$getgid(); 311 ErrorOr<FlatPtr> sys$geteuid(); 312 ErrorOr<FlatPtr> sys$getegid(); 313 ErrorOr<FlatPtr> sys$getpid(); 314 ErrorOr<FlatPtr> sys$getppid(); 315 ErrorOr<FlatPtr> sys$getresuid(Userspace<UserID*>, Userspace<UserID*>, Userspace<UserID*>); 316 ErrorOr<FlatPtr> sys$getresgid(Userspace<GroupID*>, Userspace<GroupID*>, Userspace<GroupID*>); 317 ErrorOr<FlatPtr> sys$getrusage(int, Userspace<rusage*>); 318 ErrorOr<FlatPtr> sys$umask(mode_t); 319 ErrorOr<FlatPtr> sys$open(Userspace<Syscall::SC_open_params const*>); 320 ErrorOr<FlatPtr> sys$close(int fd); 321 ErrorOr<FlatPtr> sys$read(int fd, Userspace<u8*>, size_t); 322 ErrorOr<FlatPtr> sys$pread(int fd, Userspace<u8*>, size_t, Userspace<off_t const*>); 323 ErrorOr<FlatPtr> sys$readv(int fd, Userspace<const struct iovec*> iov, int iov_count); 324 ErrorOr<FlatPtr> sys$write(int fd, Userspace<u8 const*>, size_t); 325 ErrorOr<FlatPtr> sys$pwritev(int fd, Userspace<const struct iovec*> iov, int iov_count, Userspace<off_t const*>); 326 ErrorOr<FlatPtr> sys$fstat(int fd, Userspace<stat*>); 327 ErrorOr<FlatPtr> sys$stat(Userspace<Syscall::SC_stat_params const*>); 328 ErrorOr<FlatPtr> sys$annotate_mapping(Userspace<void*>, int flags); 329 ErrorOr<FlatPtr> sys$lseek(int fd, Userspace<off_t*>, int whence); 330 ErrorOr<FlatPtr> sys$ftruncate(int fd, Userspace<off_t const*>); 331 ErrorOr<FlatPtr> sys$posix_fallocate(int fd, Userspace<off_t const*>, Userspace<off_t const*>); 332 ErrorOr<FlatPtr> sys$kill(pid_t pid_or_pgid, int sig); 333 [[noreturn]] void sys$exit(int status); 334 ErrorOr<FlatPtr> sys$sigreturn(RegisterState& registers); 335 ErrorOr<FlatPtr> sys$waitid(Userspace<Syscall::SC_waitid_params const*>); 336 ErrorOr<FlatPtr> sys$mmap(Userspace<Syscall::SC_mmap_params const*>); 337 ErrorOr<FlatPtr> sys$mremap(Userspace<Syscall::SC_mremap_params const*>); 338 ErrorOr<FlatPtr> sys$munmap(Userspace<void*>, size_t); 339 ErrorOr<FlatPtr> sys$set_mmap_name(Userspace<Syscall::SC_set_mmap_name_params const*>); 340 ErrorOr<FlatPtr> sys$mprotect(Userspace<void*>, size_t, int prot); 341 ErrorOr<FlatPtr> sys$madvise(Userspace<void*>, size_t, int advice); 342 ErrorOr<FlatPtr> sys$msync(Userspace<void*>, size_t, int flags); 343 ErrorOr<FlatPtr> sys$purge(int mode); 344 ErrorOr<FlatPtr> sys$poll(Userspace<Syscall::SC_poll_params const*>); 345 ErrorOr<FlatPtr> sys$get_dir_entries(int fd, Userspace<void*>, size_t); 346 ErrorOr<FlatPtr> sys$getcwd(Userspace<char*>, size_t); 347 ErrorOr<FlatPtr> sys$chdir(Userspace<char const*>, size_t); 348 ErrorOr<FlatPtr> sys$fchdir(int fd); 349 ErrorOr<FlatPtr> sys$adjtime(Userspace<timeval const*>, Userspace<timeval*>); 350 ErrorOr<FlatPtr> sys$clock_gettime(clockid_t, Userspace<timespec*>); 351 ErrorOr<FlatPtr> sys$clock_settime(clockid_t, Userspace<timespec const*>); 352 ErrorOr<FlatPtr> sys$clock_nanosleep(Userspace<Syscall::SC_clock_nanosleep_params const*>); 353 ErrorOr<FlatPtr> sys$clock_getres(Userspace<Syscall::SC_clock_getres_params const*>); 354 ErrorOr<FlatPtr> sys$gethostname(Userspace<char*>, size_t); 355 ErrorOr<FlatPtr> sys$sethostname(Userspace<char const*>, size_t); 356 ErrorOr<FlatPtr> sys$uname(Userspace<utsname*>); 357 ErrorOr<FlatPtr> sys$readlink(Userspace<Syscall::SC_readlink_params const*>); 358 ErrorOr<FlatPtr> sys$fork(RegisterState&); 359 ErrorOr<FlatPtr> sys$execve(Userspace<Syscall::SC_execve_params const*>); 360 ErrorOr<FlatPtr> sys$dup2(int old_fd, int new_fd); 361 ErrorOr<FlatPtr> sys$sigaction(int signum, Userspace<sigaction const*> act, Userspace<sigaction*> old_act); 362 ErrorOr<FlatPtr> sys$sigaltstack(Userspace<stack_t const*> ss, Userspace<stack_t*> old_ss); 363 ErrorOr<FlatPtr> sys$sigprocmask(int how, Userspace<sigset_t const*> set, Userspace<sigset_t*> old_set); 364 ErrorOr<FlatPtr> sys$sigpending(Userspace<sigset_t*>); 365 ErrorOr<FlatPtr> sys$sigsuspend(Userspace<sigset_t const*>); 366 ErrorOr<FlatPtr> sys$sigtimedwait(Userspace<sigset_t const*>, Userspace<siginfo_t*>, Userspace<timespec const*>); 367 ErrorOr<FlatPtr> sys$getgroups(size_t, Userspace<GroupID*>); 368 ErrorOr<FlatPtr> sys$setgroups(size_t, Userspace<GroupID const*>); 369 ErrorOr<FlatPtr> sys$pipe(Userspace<int*>, int flags); 370 ErrorOr<FlatPtr> sys$killpg(pid_t pgrp, int sig); 371 ErrorOr<FlatPtr> sys$seteuid(UserID); 372 ErrorOr<FlatPtr> sys$setegid(GroupID); 373 ErrorOr<FlatPtr> sys$setuid(UserID); 374 ErrorOr<FlatPtr> sys$setgid(GroupID); 375 ErrorOr<FlatPtr> sys$setreuid(UserID, UserID); 376 ErrorOr<FlatPtr> sys$setresuid(UserID, UserID, UserID); 377 ErrorOr<FlatPtr> sys$setregid(GroupID, GroupID); 378 ErrorOr<FlatPtr> sys$setresgid(GroupID, GroupID, GroupID); 379 ErrorOr<FlatPtr> sys$alarm(unsigned seconds); 380 ErrorOr<FlatPtr> sys$faccessat(Userspace<Syscall::SC_faccessat_params const*>); 381 ErrorOr<FlatPtr> sys$fcntl(int fd, int cmd, uintptr_t extra_arg); 382 ErrorOr<FlatPtr> sys$ioctl(int fd, unsigned request, FlatPtr arg); 383 ErrorOr<FlatPtr> sys$mkdir(int dirfd, Userspace<char const*> pathname, size_t path_length, mode_t mode); 384 ErrorOr<FlatPtr> sys$times(Userspace<tms*>); 385 ErrorOr<FlatPtr> sys$utime(Userspace<char const*> pathname, size_t path_length, Userspace<const struct utimbuf*>); 386 ErrorOr<FlatPtr> sys$utimensat(Userspace<Syscall::SC_utimensat_params const*>); 387 ErrorOr<FlatPtr> sys$link(Userspace<Syscall::SC_link_params const*>); 388 ErrorOr<FlatPtr> sys$unlink(int dirfd, Userspace<char const*> pathname, size_t path_length, int flags); 389 ErrorOr<FlatPtr> sys$symlink(Userspace<Syscall::SC_symlink_params const*>); 390 ErrorOr<FlatPtr> sys$rmdir(Userspace<char const*> pathname, size_t path_length); 391 ErrorOr<FlatPtr> sys$mount(Userspace<Syscall::SC_mount_params const*>); 392 ErrorOr<FlatPtr> sys$umount(Userspace<char const*> mountpoint, size_t mountpoint_length); 393 ErrorOr<FlatPtr> sys$chmod(Userspace<Syscall::SC_chmod_params const*>); 394 ErrorOr<FlatPtr> sys$fchmod(int fd, mode_t); 395 ErrorOr<FlatPtr> sys$chown(Userspace<Syscall::SC_chown_params const*>); 396 ErrorOr<FlatPtr> sys$fchown(int fd, UserID, GroupID); 397 ErrorOr<FlatPtr> sys$fsync(int fd); 398 ErrorOr<FlatPtr> sys$socket(int domain, int type, int protocol); 399 ErrorOr<FlatPtr> sys$bind(int sockfd, Userspace<sockaddr const*> addr, socklen_t); 400 ErrorOr<FlatPtr> sys$listen(int sockfd, int backlog); 401 ErrorOr<FlatPtr> sys$accept4(Userspace<Syscall::SC_accept4_params const*>); 402 ErrorOr<FlatPtr> sys$connect(int sockfd, Userspace<sockaddr const*>, socklen_t); 403 ErrorOr<FlatPtr> sys$shutdown(int sockfd, int how); 404 ErrorOr<FlatPtr> sys$sendmsg(int sockfd, Userspace<const struct msghdr*>, int flags); 405 ErrorOr<FlatPtr> sys$recvmsg(int sockfd, Userspace<struct msghdr*>, int flags); 406 ErrorOr<FlatPtr> sys$getsockopt(Userspace<Syscall::SC_getsockopt_params const*>); 407 ErrorOr<FlatPtr> sys$setsockopt(Userspace<Syscall::SC_setsockopt_params const*>); 408 ErrorOr<FlatPtr> sys$getsockname(Userspace<Syscall::SC_getsockname_params const*>); 409 ErrorOr<FlatPtr> sys$getpeername(Userspace<Syscall::SC_getpeername_params const*>); 410 ErrorOr<FlatPtr> sys$socketpair(Userspace<Syscall::SC_socketpair_params const*>); 411 ErrorOr<FlatPtr> sys$scheduler_set_parameters(Userspace<Syscall::SC_scheduler_parameters_params const*>); 412 ErrorOr<FlatPtr> sys$scheduler_get_parameters(Userspace<Syscall::SC_scheduler_parameters_params*>); 413 ErrorOr<FlatPtr> sys$create_thread(void* (*)(void*), Userspace<Syscall::SC_create_thread_params const*>); 414 [[noreturn]] void sys$exit_thread(Userspace<void*>, Userspace<void*>, size_t); 415 ErrorOr<FlatPtr> sys$join_thread(pid_t tid, Userspace<void**> exit_value); 416 ErrorOr<FlatPtr> sys$detach_thread(pid_t tid); 417 ErrorOr<FlatPtr> sys$set_thread_name(pid_t tid, Userspace<char const*> buffer, size_t buffer_size); 418 ErrorOr<FlatPtr> sys$get_thread_name(pid_t tid, Userspace<char*> buffer, size_t buffer_size); 419 ErrorOr<FlatPtr> sys$kill_thread(pid_t tid, int signal); 420 ErrorOr<FlatPtr> sys$rename(Userspace<Syscall::SC_rename_params const*>); 421 ErrorOr<FlatPtr> sys$mknod(Userspace<Syscall::SC_mknod_params const*>); 422 ErrorOr<FlatPtr> sys$realpath(Userspace<Syscall::SC_realpath_params const*>); 423 ErrorOr<FlatPtr> sys$getrandom(Userspace<void*>, size_t, unsigned int); 424 ErrorOr<FlatPtr> sys$getkeymap(Userspace<Syscall::SC_getkeymap_params const*>); 425 ErrorOr<FlatPtr> sys$setkeymap(Userspace<Syscall::SC_setkeymap_params const*>); 426 ErrorOr<FlatPtr> sys$profiling_enable(pid_t, Userspace<u64 const*>); 427 ErrorOr<FlatPtr> profiling_enable(pid_t, u64 event_mask); 428 ErrorOr<FlatPtr> sys$profiling_disable(pid_t); 429 ErrorOr<FlatPtr> sys$profiling_free_buffer(pid_t); 430 ErrorOr<FlatPtr> sys$futex(Userspace<Syscall::SC_futex_params const*>); 431 ErrorOr<FlatPtr> sys$pledge(Userspace<Syscall::SC_pledge_params const*>); 432 ErrorOr<FlatPtr> sys$unveil(Userspace<Syscall::SC_unveil_params const*>); 433 ErrorOr<FlatPtr> sys$perf_event(int type, FlatPtr arg1, FlatPtr arg2); 434 ErrorOr<FlatPtr> sys$perf_register_string(Userspace<char const*>, size_t); 435 ErrorOr<FlatPtr> sys$get_stack_bounds(Userspace<FlatPtr*> stack_base, Userspace<size_t*> stack_size); 436 ErrorOr<FlatPtr> sys$ptrace(Userspace<Syscall::SC_ptrace_params const*>); 437 ErrorOr<FlatPtr> sys$sendfd(int sockfd, int fd); 438 ErrorOr<FlatPtr> sys$recvfd(int sockfd, int options); 439 ErrorOr<FlatPtr> sys$sysconf(int name); 440 ErrorOr<FlatPtr> sys$disown(ProcessID); 441 ErrorOr<FlatPtr> sys$allocate_tls(Userspace<char const*> initial_data, size_t); 442 ErrorOr<FlatPtr> sys$prctl(int option, FlatPtr arg1, FlatPtr arg2); 443 ErrorOr<FlatPtr> sys$anon_create(size_t, int options); 444 ErrorOr<FlatPtr> sys$statvfs(Userspace<Syscall::SC_statvfs_params const*> user_params); 445 ErrorOr<FlatPtr> sys$fstatvfs(int fd, statvfs* buf); 446 ErrorOr<FlatPtr> sys$map_time_page(); 447 ErrorOr<FlatPtr> sys$jail_create(Userspace<Syscall::SC_jail_create_params*> user_params); 448 ErrorOr<FlatPtr> sys$jail_attach(Userspace<Syscall::SC_jail_attach_params const*> user_params); 449 ErrorOr<FlatPtr> sys$get_root_session_id(pid_t force_sid); 450 451 template<bool sockname, typename Params> 452 ErrorOr<void> get_sock_or_peer_name(Params const&); 453 454 static void initialize(); 455 456 [[noreturn]] void crash(int signal, Optional<RegisterState const&> regs, bool out_of_memory = false); 457 [[nodiscard]] siginfo_t wait_info() const; 458 459 const TTY* tty() const { return m_tty; } 460 void set_tty(TTY*); 461 462 u32 m_ticks_in_user { 0 }; 463 u32 m_ticks_in_kernel { 0 }; 464 465 u32 m_ticks_in_user_for_dead_children { 0 }; 466 u32 m_ticks_in_kernel_for_dead_children { 0 }; 467 468 NonnullRefPtr<Custody> current_directory(); 469 RefPtr<Custody> executable(); 470 RefPtr<Custody const> executable() const; 471 472 static constexpr size_t max_arguments_size = Thread::default_userspace_stack_size / 8; 473 static constexpr size_t max_environment_size = Thread::default_userspace_stack_size / 8; 474 static constexpr size_t max_auxiliary_size = Thread::default_userspace_stack_size / 8; 475 Vector<NonnullOwnPtr<KString>> const& arguments() const { return m_arguments; }; 476 Vector<NonnullOwnPtr<KString>> const& environment() const { return m_environment; }; 477 478 ErrorOr<void> exec(NonnullOwnPtr<KString> path, Vector<NonnullOwnPtr<KString>> arguments, Vector<NonnullOwnPtr<KString>> environment, Thread*& new_main_thread, InterruptsState& previous_interrupts_state, int recursion_depth = 0); 479 480 ErrorOr<LoadResult> load(NonnullRefPtr<OpenFileDescription> main_program_description, RefPtr<OpenFileDescription> interpreter_description, const ElfW(Ehdr) & main_program_header); 481 482 void terminate_due_to_signal(u8 signal); 483 ErrorOr<void> send_signal(u8 signal, Process* sender); 484 485 u8 termination_signal() const 486 { 487 return with_protected_data([](auto& protected_data) -> u8 { 488 return protected_data.termination_signal; 489 }); 490 } 491 u8 termination_status() const 492 { 493 return with_protected_data([](auto& protected_data) { return protected_data.termination_status; }); 494 } 495 496 u16 thread_count() const 497 { 498 return with_protected_data([](auto& protected_data) { 499 return protected_data.thread_count.load(AK::MemoryOrder::memory_order_relaxed); 500 }); 501 } 502 503 Mutex& big_lock() { return m_big_lock; } 504 Mutex& ptrace_lock() { return m_ptrace_lock; } 505 506 bool has_promises() const 507 { 508 return with_protected_data([](auto& protected_data) { return protected_data.has_promises.load(); }); 509 } 510 bool has_promised(Pledge pledge) const 511 { 512 return with_protected_data([&](auto& protected_data) { 513 return (protected_data.promises & (1U << (u32)pledge)) != 0; 514 }); 515 } 516 517 VeilState veil_state() const 518 { 519 return m_unveil_data.with([&](auto const& unveil_data) { return unveil_data.state; }); 520 } 521 522 struct UnveilData { 523 explicit UnveilData(UnveilNode&& p) 524 : paths(move(p)) 525 { 526 } 527 VeilState state { VeilState::None }; 528 UnveilNode paths; 529 }; 530 531 auto& unveil_data() { return m_unveil_data; } 532 auto const& unveil_data() const { return m_unveil_data; } 533 534 auto& exec_unveil_data() { return m_exec_unveil_data; } 535 auto const& exec_unveil_data() const { return m_exec_unveil_data; } 536 537 bool wait_for_tracer_at_next_execve() const 538 { 539 return m_wait_for_tracer_at_next_execve; 540 } 541 void set_wait_for_tracer_at_next_execve(bool val) 542 { 543 m_wait_for_tracer_at_next_execve = val; 544 } 545 546 ErrorOr<void> peek_user_data(Span<u8> destination, Userspace<u8 const*> address); 547 ErrorOr<FlatPtr> peek_user_data(Userspace<FlatPtr const*> address); 548 ErrorOr<void> poke_user_data(Userspace<FlatPtr*> address, FlatPtr data); 549 550 void disowned_by_waiter(Process& process); 551 void unblock_waiters(Thread::WaitBlocker::UnblockFlags, u8 signal = 0); 552 Thread::WaitBlockerSet& wait_blocker_set() { return m_wait_blocker_set; } 553 554 template<typename Callback> 555 ErrorOr<void> for_each_coredump_property(Callback callback) const 556 { 557 return m_coredump_properties.with([&](auto const& coredump_properties) -> ErrorOr<void> { 558 for (auto const& property : coredump_properties) { 559 if (property.key && property.value) 560 TRY(callback(*property.key, *property.value)); 561 } 562 563 return {}; 564 }); 565 } 566 567 ErrorOr<void> set_coredump_property(NonnullOwnPtr<KString> key, NonnullOwnPtr<KString> value); 568 ErrorOr<void> try_set_coredump_property(StringView key, StringView value); 569 570 Vector<NonnullLockRefPtr<Thread>> const& threads_for_coredump(Badge<Coredump>) const { return m_threads_for_coredump; } 571 572 PerformanceEventBuffer* perf_events() { return m_perf_event_buffer; } 573 PerformanceEventBuffer const* perf_events() const { return m_perf_event_buffer; } 574 575 SpinlockProtected<OwnPtr<Memory::AddressSpace>, LockRank::None>& address_space() { return m_space; } 576 SpinlockProtected<OwnPtr<Memory::AddressSpace>, LockRank::None> const& address_space() const { return m_space; } 577 578 VirtualAddress signal_trampoline() const 579 { 580 return with_protected_data([](auto& protected_data) { return protected_data.signal_trampoline; }); 581 } 582 583 ErrorOr<void> require_promise(Pledge); 584 ErrorOr<void> require_no_promises() const; 585 586 ErrorOr<void> validate_mmap_prot(int prot, bool map_stack, bool map_anonymous, Memory::Region const* region = nullptr) const; 587 ErrorOr<void> validate_inode_mmap_prot(int prot, bool description_readable, bool description_writable, bool map_shared) const; 588 589private: 590 friend class MemoryManager; 591 friend class Scheduler; 592 friend class Region; 593 friend class PerformanceManager; 594 595 bool add_thread(Thread&); 596 bool remove_thread(Thread&); 597 598 Process(NonnullOwnPtr<KString> name, NonnullRefPtr<Credentials>, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory, RefPtr<Custody> executable, TTY* tty, UnveilNode unveil_tree, UnveilNode exec_unveil_tree); 599 static ErrorOr<NonnullLockRefPtr<Process>> try_create(LockRefPtr<Thread>& first_thread, NonnullOwnPtr<KString> name, UserID, GroupID, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory = nullptr, RefPtr<Custody> executable = nullptr, TTY* = nullptr, Process* fork_parent = nullptr); 600 ErrorOr<void> attach_resources(NonnullOwnPtr<Memory::AddressSpace>&&, LockRefPtr<Thread>& first_thread, Process* fork_parent); 601 static ProcessID allocate_pid(); 602 603 void kill_threads_except_self(); 604 void kill_all_threads(); 605 ErrorOr<void> dump_core(); 606 ErrorOr<void> dump_perfcore(); 607 bool create_perf_events_buffer_if_needed(); 608 void delete_perf_events_buffer(); 609 610 ErrorOr<void> do_exec(NonnullRefPtr<OpenFileDescription> main_program_description, Vector<NonnullOwnPtr<KString>> arguments, Vector<NonnullOwnPtr<KString>> environment, RefPtr<OpenFileDescription> interpreter_description, Thread*& new_main_thread, InterruptsState& previous_interrupts_state, const ElfW(Ehdr) & main_program_header); 611 ErrorOr<FlatPtr> do_write(OpenFileDescription&, UserOrKernelBuffer const&, size_t, Optional<off_t> = {}); 612 613 ErrorOr<FlatPtr> do_statvfs(FileSystem const& path, Custody const*, statvfs* buf); 614 615 ErrorOr<RefPtr<OpenFileDescription>> find_elf_interpreter_for_executable(StringView path, ElfW(Ehdr) const& main_executable_header, size_t main_executable_header_size, size_t file_size); 616 617 ErrorOr<void> do_kill(Process&, int signal); 618 ErrorOr<void> do_killpg(ProcessGroupID pgrp, int signal); 619 ErrorOr<void> do_killall(int signal); 620 ErrorOr<void> do_killself(int signal); 621 622 ErrorOr<siginfo_t> do_waitid(Variant<Empty, NonnullLockRefPtr<Process>, NonnullLockRefPtr<ProcessGroup>> waitee, int options); 623 624 static ErrorOr<NonnullOwnPtr<KString>> get_syscall_path_argument(Userspace<char const*> user_path, size_t path_length); 625 static ErrorOr<NonnullOwnPtr<KString>> get_syscall_path_argument(Syscall::StringArgument const&); 626 627 bool has_tracee_thread(ProcessID tracer_pid); 628 629 void clear_signal_handlers_for_exec(); 630 void clear_futex_queues_on_exec(); 631 632 ErrorOr<GlobalFutexKey> get_futex_key(FlatPtr user_address, bool shared); 633 634 ErrorOr<void> remap_range_as_stack(FlatPtr address, size_t size); 635 636 ErrorOr<FlatPtr> read_impl(int fd, Userspace<u8*> buffer, size_t size); 637 638public: 639 ErrorOr<void> traverse_as_directory(FileSystemID, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const; 640 ErrorOr<NonnullRefPtr<Inode>> lookup_as_directory(ProcFS&, StringView name) const; 641 ErrorOr<void> procfs_get_fds_stats(KBufferBuilder& builder) const; 642 ErrorOr<void> procfs_get_perf_events(KBufferBuilder& builder) const; 643 ErrorOr<void> procfs_get_unveil_stats(KBufferBuilder& builder) const; 644 ErrorOr<void> procfs_get_pledge_stats(KBufferBuilder& builder) const; 645 ErrorOr<void> procfs_get_virtual_memory_stats(KBufferBuilder& builder) const; 646 ErrorOr<void> procfs_get_binary_link(KBufferBuilder& builder) const; 647 ErrorOr<void> procfs_get_current_work_directory_link(KBufferBuilder& builder) const; 648 ErrorOr<void> procfs_get_command_line(KBufferBuilder& builder) const; 649 mode_t binary_link_required_mode() const; 650 ErrorOr<void> procfs_get_thread_stack(ThreadID thread_id, KBufferBuilder& builder) const; 651 ErrorOr<void> traverse_stacks_directory(FileSystemID, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const; 652 ErrorOr<NonnullRefPtr<Inode>> lookup_stacks_directory(ProcFS&, StringView name) const; 653 ErrorOr<size_t> procfs_get_file_description_link(unsigned fd, KBufferBuilder& builder) const; 654 ErrorOr<void> traverse_file_descriptions_directory(FileSystemID, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const; 655 ErrorOr<NonnullRefPtr<Inode>> lookup_file_descriptions_directory(ProcFS&, StringView name) const; 656 ErrorOr<NonnullRefPtr<Inode>> lookup_children_directory(ProcFS&, StringView name) const; 657 ErrorOr<void> traverse_children_directory(FileSystemID, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const; 658 ErrorOr<size_t> procfs_get_child_process_link(ProcessID child_pid, KBufferBuilder& builder) const; 659 660private: 661 inline PerformanceEventBuffer* current_perf_events_buffer() 662 { 663 if (g_profiling_all_threads) 664 return g_global_perf_events; 665 if (m_profiling) 666 return m_perf_event_buffer.ptr(); 667 return nullptr; 668 } 669 670 SpinlockProtected<NonnullOwnPtr<KString>, LockRank::None> m_name; 671 672 SpinlockProtected<OwnPtr<Memory::AddressSpace>, LockRank::None> m_space; 673 674 LockRefPtr<ProcessGroup> m_pg; 675 676 RecursiveSpinlock<LockRank::None> mutable m_protected_data_lock; 677 AtomicEdgeAction<u32> m_protected_data_refs; 678 void protect_data(); 679 void unprotect_data(); 680 681 OwnPtr<ThreadTracer> m_tracer; 682 683public: 684 class OpenFileDescriptionAndFlags { 685 public: 686 bool is_valid() const { return !m_description.is_null(); } 687 bool is_allocated() const { return m_is_allocated; } 688 void allocate() 689 { 690 VERIFY(!m_is_allocated); 691 VERIFY(!is_valid()); 692 m_is_allocated = true; 693 } 694 void deallocate() 695 { 696 VERIFY(m_is_allocated); 697 VERIFY(!is_valid()); 698 m_is_allocated = false; 699 } 700 701 OpenFileDescription* description() { return m_description; } 702 OpenFileDescription const* description() const { return m_description; } 703 u32 flags() const { return m_flags; } 704 void set_flags(u32 flags) { m_flags = flags; } 705 706 void clear(); 707 void set(NonnullRefPtr<OpenFileDescription>, u32 flags = 0); 708 709 private: 710 RefPtr<OpenFileDescription> m_description; 711 bool m_is_allocated { false }; 712 u32 m_flags { 0 }; 713 }; 714 715 class ScopedDescriptionAllocation; 716 class OpenFileDescriptions { 717 AK_MAKE_NONCOPYABLE(OpenFileDescriptions); 718 AK_MAKE_NONMOVABLE(OpenFileDescriptions); 719 friend class Process; 720 721 public: 722 OpenFileDescriptions() { } 723 ALWAYS_INLINE OpenFileDescriptionAndFlags const& operator[](size_t i) const { return at(i); } 724 ALWAYS_INLINE OpenFileDescriptionAndFlags& operator[](size_t i) { return at(i); } 725 726 ErrorOr<void> try_clone(Kernel::Process::OpenFileDescriptions const& other) 727 { 728 TRY(try_resize(other.m_fds_metadatas.size())); 729 730 for (size_t i = 0; i < other.m_fds_metadatas.size(); ++i) { 731 m_fds_metadatas[i] = other.m_fds_metadatas[i]; 732 } 733 return {}; 734 } 735 736 OpenFileDescriptionAndFlags const& at(size_t i) const; 737 OpenFileDescriptionAndFlags& at(size_t i); 738 739 OpenFileDescriptionAndFlags const* get_if_valid(size_t i) const; 740 OpenFileDescriptionAndFlags* get_if_valid(size_t i); 741 742 void enumerate(Function<void(OpenFileDescriptionAndFlags const&)>) const; 743 ErrorOr<void> try_enumerate(Function<ErrorOr<void>(OpenFileDescriptionAndFlags const&)>) const; 744 void change_each(Function<void(OpenFileDescriptionAndFlags&)>); 745 746 ErrorOr<ScopedDescriptionAllocation> allocate(int first_candidate_fd = 0); 747 size_t open_count() const; 748 749 ErrorOr<void> try_resize(size_t size) { return m_fds_metadatas.try_resize(size); } 750 751 static constexpr size_t max_open() 752 { 753 return s_max_open_file_descriptors; 754 } 755 756 void clear() 757 { 758 m_fds_metadatas.clear(); 759 } 760 761 ErrorOr<NonnullRefPtr<OpenFileDescription>> open_file_description(int fd) const; 762 763 private: 764 static constexpr size_t s_max_open_file_descriptors { FD_SETSIZE }; 765 Vector<OpenFileDescriptionAndFlags> m_fds_metadatas; 766 }; 767 768 class ScopedDescriptionAllocation { 769 AK_MAKE_NONCOPYABLE(ScopedDescriptionAllocation); 770 771 public: 772 ScopedDescriptionAllocation() = default; 773 ScopedDescriptionAllocation(int tracked_fd, OpenFileDescriptionAndFlags* description) 774 : fd(tracked_fd) 775 , m_description(description) 776 { 777 } 778 779 ScopedDescriptionAllocation(ScopedDescriptionAllocation&& other) 780 : fd(other.fd) 781 { 782 // Take over the responsibility of tracking to deallocation. 783 swap(m_description, other.m_description); 784 } 785 786 ScopedDescriptionAllocation& operator=(ScopedDescriptionAllocation&& other) 787 { 788 if (this != &other) { 789 m_description = exchange(other.m_description, nullptr); 790 fd = exchange(other.fd, -1); 791 } 792 return *this; 793 } 794 795 ~ScopedDescriptionAllocation() 796 { 797 if (m_description && m_description->is_allocated() && !m_description->is_valid()) { 798 m_description->deallocate(); 799 } 800 } 801 802 int fd { -1 }; 803 804 private: 805 OpenFileDescriptionAndFlags* m_description { nullptr }; 806 }; 807 808 MutexProtected<OpenFileDescriptions>& fds() { return m_fds; } 809 MutexProtected<OpenFileDescriptions> const& fds() const { return m_fds; } 810 811 ErrorOr<NonnullRefPtr<OpenFileDescription>> open_file_description(int fd) 812 { 813 return m_fds.with_shared([fd](auto& fds) { return fds.open_file_description(fd); }); 814 } 815 816 ErrorOr<NonnullRefPtr<OpenFileDescription>> open_file_description(int fd) const 817 { 818 return m_fds.with_shared([fd](auto& fds) { return fds.open_file_description(fd); }); 819 } 820 821 ErrorOr<ScopedDescriptionAllocation> allocate_fd() 822 { 823 return m_fds.with_exclusive([](auto& fds) { return fds.allocate(); }); 824 } 825 826private: 827 ErrorOr<NonnullRefPtr<Custody>> custody_for_dirfd(int dirfd); 828 829 SpinlockProtected<Thread::ListInProcess, LockRank::None>& thread_list() { return m_thread_list; } 830 SpinlockProtected<Thread::ListInProcess, LockRank::None> const& thread_list() const { return m_thread_list; } 831 832 ErrorOr<NonnullRefPtr<Thread>> get_thread_from_pid_or_tid(pid_t pid_or_tid, Syscall::SchedulerParametersMode mode); 833 834 SpinlockProtected<Thread::ListInProcess, LockRank::None> m_thread_list {}; 835 836 MutexProtected<OpenFileDescriptions> m_fds; 837 838 bool const m_is_kernel_process; 839 Atomic<State> m_state { State::Running }; 840 bool m_profiling { false }; 841 Atomic<bool, AK::MemoryOrder::memory_order_relaxed> m_is_stopped { false }; 842 bool m_should_generate_coredump { false }; 843 844 SpinlockProtected<RefPtr<Custody>, LockRank::None> m_executable; 845 846 SpinlockProtected<RefPtr<Custody>, LockRank::None> m_current_directory; 847 848 Vector<NonnullOwnPtr<KString>> m_arguments; 849 Vector<NonnullOwnPtr<KString>> m_environment; 850 851 LockRefPtr<TTY> m_tty; 852 853 LockWeakPtr<Memory::Region> m_master_tls_region; 854 855 IntrusiveListNode<Process> m_jail_process_list_node; 856 IntrusiveListNode<Process> m_all_processes_list_node; 857 858public: 859 using AllProcessesList = IntrusiveListRelaxedConst<&Process::m_all_processes_list_node>; 860 using JailProcessList = IntrusiveListRelaxedConst<&Process::m_jail_process_list_node>; 861 862private: 863 SpinlockProtected<RefPtr<ProcessList>, LockRank::None> m_jail_process_list; 864 SpinlockProtected<RefPtr<Jail>, LockRank::Process> m_attached_jail {}; 865 866 size_t m_master_tls_size { 0 }; 867 size_t m_master_tls_alignment { 0 }; 868 869 Mutex m_big_lock { "Process"sv, Mutex::MutexBehavior::BigLock }; 870 Mutex m_ptrace_lock { "ptrace"sv }; 871 872 LockRefPtr<Timer> m_alarm_timer; 873 874 SpinlockProtected<UnveilData, LockRank::None> m_unveil_data; 875 SpinlockProtected<UnveilData, LockRank::None> m_exec_unveil_data; 876 877 OwnPtr<PerformanceEventBuffer> m_perf_event_buffer; 878 879 // This member is used in the implementation of ptrace's PT_TRACEME flag. 880 // If it is set to true, the process will stop at the next execve syscall 881 // and wait for a tracer to attach. 882 bool m_wait_for_tracer_at_next_execve { false }; 883 884 Thread::WaitBlockerSet m_wait_blocker_set; 885 886 struct CoredumpProperty { 887 OwnPtr<KString> key; 888 OwnPtr<KString> value; 889 }; 890 891 SpinlockProtected<Array<CoredumpProperty, 4>, LockRank::None> m_coredump_properties {}; 892 Vector<NonnullLockRefPtr<Thread>> m_threads_for_coredump; 893 894 struct SignalActionData { 895 VirtualAddress handler_or_sigaction; 896 int flags { 0 }; 897 u32 mask { 0 }; 898 }; 899 Array<SignalActionData, NSIG> m_signal_action_data; 900 901 static_assert(sizeof(ProtectedValues) < (PAGE_SIZE)); 902 alignas(4096) ProtectedValues m_protected_values_do_not_access_directly; 903 u8 m_protected_values_padding[PAGE_SIZE - sizeof(ProtectedValues)]; 904 905public: 906 static SpinlockProtected<Process::AllProcessesList, LockRank::None>& all_instances(); 907}; 908 909class ProcessList : public RefCounted<ProcessList> { 910public: 911 static ErrorOr<NonnullRefPtr<ProcessList>> create(); 912 SpinlockProtected<Process::JailProcessList, LockRank::None>& attached_processes() { return m_attached_processes; } 913 SpinlockProtected<Process::JailProcessList, LockRank::None> const& attached_processes() const { return m_attached_processes; } 914 915private: 916 ProcessList() = default; 917 SpinlockProtected<Process::JailProcessList, LockRank::None> m_attached_processes; 918}; 919 920// Note: Process object should be 2 pages of 4096 bytes each. 921// It's not expected that the Process object will expand further because the first 922// page is used for all unprotected values (which should be plenty of space for them). 923// The second page is being used exclusively for write-protected values. 924static_assert(AssertSize<Process, (PAGE_SIZE * 2)>()); 925 926extern RecursiveSpinlock<LockRank::None> g_profiling_lock; 927 928template<IteratorFunction<Thread&> Callback> 929inline IterationDecision Process::for_each_thread(Callback callback) 930{ 931 return thread_list().with([&](auto& thread_list) -> IterationDecision { 932 for (auto& thread : thread_list) { 933 IterationDecision decision = callback(thread); 934 if (decision != IterationDecision::Continue) 935 return decision; 936 } 937 return IterationDecision::Continue; 938 }); 939} 940 941template<IteratorFunction<Process&> Callback> 942inline void Process::for_each_ignoring_jails(Callback callback) 943{ 944 Process::all_instances().with([&](auto const& list) { 945 for (auto it = list.begin(); it != list.end();) { 946 auto& process = *it; 947 ++it; 948 if (callback(process) == IterationDecision::Break) 949 break; 950 } 951 }); 952} 953 954template<IteratorFunction<Thread&> Callback> 955inline IterationDecision Process::for_each_thread(Callback callback) const 956{ 957 return thread_list().with([&](auto& thread_list) -> IterationDecision { 958 for (auto& thread : thread_list) { 959 IterationDecision decision = callback(thread); 960 if (decision != IterationDecision::Continue) 961 return decision; 962 } 963 return IterationDecision::Continue; 964 }); 965} 966 967template<VoidFunction<Thread&> Callback> 968inline IterationDecision Process::for_each_thread(Callback callback) const 969{ 970 thread_list().with([&](auto& thread_list) { 971 for (auto& thread : thread_list) 972 callback(thread); 973 }); 974 return IterationDecision::Continue; 975} 976 977inline ErrorOr<void> Process::try_for_each_thread(Function<ErrorOr<void>(Thread const&)> callback) const 978{ 979 return thread_list().with([&](auto& thread_list) -> ErrorOr<void> { 980 for (auto& thread : thread_list) 981 TRY(callback(thread)); 982 return {}; 983 }); 984} 985 986template<VoidFunction<Thread&> Callback> 987inline IterationDecision Process::for_each_thread(Callback callback) 988{ 989 thread_list().with([&](auto& thread_list) { 990 for (auto& thread : thread_list) 991 callback(thread); 992 }); 993 return IterationDecision::Continue; 994} 995 996inline ProcessID Thread::pid() const 997{ 998 return m_process->pid(); 999} 1000 1001} 1002 1003#define VERIFY_PROCESS_BIG_LOCK_ACQUIRED(process) \ 1004 VERIFY(process->big_lock().is_exclusively_locked_by_current_thread()) 1005 1006#define VERIFY_NO_PROCESS_BIG_LOCK(process) \ 1007 VERIFY(!process->big_lock().is_exclusively_locked_by_current_thread()) 1008 1009inline ErrorOr<NonnullOwnPtr<KString>> try_copy_kstring_from_user(Kernel::Syscall::StringArgument const& string) 1010{ 1011 Userspace<char const*> characters((FlatPtr)string.characters); 1012 return try_copy_kstring_from_user(characters, string.length); 1013} 1014 1015template<> 1016struct AK::Formatter<Kernel::Process> : AK::Formatter<FormatString> { 1017 ErrorOr<void> format(FormatBuilder& builder, Kernel::Process const& value) 1018 { 1019 return value.name().with([&](auto& process_name) { 1020 return AK::Formatter<FormatString>::format(builder, "{}({})"sv, process_name->view(), value.pid().value()); 1021 }); 1022 } 1023}; 1024 1025namespace AK { 1026template<> 1027struct Traits<Kernel::GlobalFutexKey> : public GenericTraits<Kernel::GlobalFutexKey> { 1028 static unsigned hash(Kernel::GlobalFutexKey const& futex_key) { return pair_int_hash(ptr_hash(futex_key.raw.parent), ptr_hash(futex_key.raw.offset)); } 1029 static bool equals(Kernel::GlobalFutexKey const& a, Kernel::GlobalFutexKey const& b) { return a.raw.parent == b.raw.parent && a.raw.offset == b.raw.offset; } 1030}; 1031};