diff --git a/Kernel/API/Syscall.h b/Kernel/API/Syscall.h index 88854ef726..1357b9fc54 100644 --- a/Kernel/API/Syscall.h +++ b/Kernel/API/Syscall.h @@ -28,165 +28,170 @@ typedef u32 socklen_t; namespace Kernel { -#define ENUMERATE_SYSCALLS(S) \ - S(yield) \ - S(open) \ - S(close) \ - S(read) \ - S(lseek) \ - S(kill) \ - S(getuid) \ - S(exit) \ - S(geteuid) \ - S(getegid) \ - S(getgid) \ - S(getpid) \ - S(getppid) \ - S(getresuid) \ - S(getresgid) \ - S(waitid) \ - S(mmap) \ - S(munmap) \ - S(get_dir_entries) \ - S(getcwd) \ - S(gettimeofday) \ - S(gethostname) \ - S(sethostname) \ - S(chdir) \ - S(uname) \ - S(set_mmap_name) \ - S(readlink) \ - S(write) \ - S(ttyname) \ - S(stat) \ - S(getsid) \ - S(setsid) \ - S(getpgid) \ - S(setpgid) \ - S(getpgrp) \ - S(fork) \ - S(execve) \ - S(dup2) \ - S(sigaction) \ - S(umask) \ - S(getgroups) \ - S(setgroups) \ - S(sigreturn) \ - S(sigprocmask) \ - S(sigpending) \ - S(pipe) \ - S(killpg) \ - S(seteuid) \ - S(setegid) \ - S(setuid) \ - S(setgid) \ - S(setreuid) \ - S(setresuid) \ - S(setresgid) \ - S(alarm) \ - S(fstat) \ - S(access) \ - S(fcntl) \ - S(ioctl) \ - S(mkdir) \ - S(times) \ - S(utime) \ - S(sync) \ - S(ptsname) \ - S(select) \ - S(unlink) \ - S(poll) \ - S(rmdir) \ - S(chmod) \ - S(socket) \ - S(bind) \ - S(accept4) \ - S(listen) \ - S(connect) \ - S(link) \ - S(chown) \ - S(fchmod) \ - S(symlink) \ - S(sendmsg) \ - S(recvmsg) \ - S(getsockopt) \ - S(setsockopt) \ - S(create_thread) \ - S(gettid) \ - S(rename) \ - S(ftruncate) \ - S(exit_thread) \ - S(mknod) \ - S(writev) \ - S(beep) \ - S(getsockname) \ - S(getpeername) \ - S(socketpair) \ - S(sched_setparam) \ - S(sched_getparam) \ - S(fchown) \ - S(halt) \ - S(reboot) \ - S(mount) \ - S(umount) \ - S(dump_backtrace) \ - S(dbgputch) \ - S(dbgputstr) \ - S(create_inode_watcher) \ - S(inode_watcher_add_watch) \ - S(inode_watcher_remove_watch) \ - S(mprotect) \ - S(realpath) \ - S(get_process_name) \ - S(fchdir) \ - S(getrandom) \ - S(getkeymap) \ - S(setkeymap) \ - S(clock_gettime) \ - S(clock_settime) \ - S(clock_nanosleep) \ - S(join_thread) \ - S(module_load) \ - S(module_unload) \ - S(detach_thread) \ - S(set_thread_name) \ - S(get_thread_name) \ - S(madvise) \ - S(purge) \ - S(profiling_enable) \ - S(profiling_disable) \ - S(profiling_free_buffer) \ - S(futex) \ - S(chroot) \ - S(pledge) \ - S(unveil) \ - S(perf_event) \ - S(shutdown) \ - S(get_stack_bounds) \ - S(ptrace) \ - S(sendfd) \ - S(recvfd) \ - S(sysconf) \ - S(set_process_name) \ - S(disown) \ - S(adjtime) \ - S(allocate_tls) \ - S(prctl) \ - S(mremap) \ - S(set_coredump_metadata) \ - S(anon_create) \ - S(msyscall) \ - S(readv) \ - S(emuctl) \ - S(statvfs) \ - S(fstatvfs) \ - S(kill_thread) +enum class NeedsBigProcessLock { + Yes, + No +}; + +#define ENUMERATE_SYSCALLS(S) \ + S(yield, NeedsBigProcessLock::Yes) \ + S(open, NeedsBigProcessLock::Yes) \ + S(close, NeedsBigProcessLock::Yes) \ + S(read, NeedsBigProcessLock::Yes) \ + S(lseek, NeedsBigProcessLock::Yes) \ + S(kill, NeedsBigProcessLock::Yes) \ + S(getuid, NeedsBigProcessLock::Yes) \ + S(exit, NeedsBigProcessLock::Yes) \ + S(geteuid, NeedsBigProcessLock::Yes) \ + S(getegid, NeedsBigProcessLock::Yes) \ + S(getgid, NeedsBigProcessLock::Yes) \ + S(getpid, NeedsBigProcessLock::Yes) \ + S(getppid, NeedsBigProcessLock::Yes) \ + S(getresuid, NeedsBigProcessLock::Yes) \ + S(getresgid, NeedsBigProcessLock::Yes) \ + S(waitid, NeedsBigProcessLock::Yes) \ + S(mmap, NeedsBigProcessLock::Yes) \ + S(munmap, NeedsBigProcessLock::Yes) \ + S(get_dir_entries, NeedsBigProcessLock::Yes) \ + S(getcwd, NeedsBigProcessLock::Yes) \ + S(gettimeofday, NeedsBigProcessLock::Yes) \ + S(gethostname, NeedsBigProcessLock::Yes) \ + S(sethostname, NeedsBigProcessLock::Yes) \ + S(chdir, NeedsBigProcessLock::Yes) \ + S(uname, NeedsBigProcessLock::Yes) \ + S(set_mmap_name, NeedsBigProcessLock::Yes) \ + S(readlink, NeedsBigProcessLock::Yes) \ + S(write, NeedsBigProcessLock::Yes) \ + S(ttyname, NeedsBigProcessLock::Yes) \ + S(stat, NeedsBigProcessLock::Yes) \ + S(getsid, NeedsBigProcessLock::Yes) \ + S(setsid, NeedsBigProcessLock::Yes) \ + S(getpgid, NeedsBigProcessLock::Yes) \ + S(setpgid, NeedsBigProcessLock::Yes) \ + S(getpgrp, NeedsBigProcessLock::Yes) \ + S(fork, NeedsBigProcessLock::Yes) \ + S(execve, NeedsBigProcessLock::Yes) \ + S(dup2, NeedsBigProcessLock::Yes) \ + S(sigaction, NeedsBigProcessLock::Yes) \ + S(umask, NeedsBigProcessLock::Yes) \ + S(getgroups, NeedsBigProcessLock::Yes) \ + S(setgroups, NeedsBigProcessLock::Yes) \ + S(sigreturn, NeedsBigProcessLock::Yes) \ + S(sigprocmask, NeedsBigProcessLock::Yes) \ + S(sigpending, NeedsBigProcessLock::Yes) \ + S(pipe, NeedsBigProcessLock::Yes) \ + S(killpg, NeedsBigProcessLock::Yes) \ + S(seteuid, NeedsBigProcessLock::Yes) \ + S(setegid, NeedsBigProcessLock::Yes) \ + S(setuid, NeedsBigProcessLock::Yes) \ + S(setgid, NeedsBigProcessLock::Yes) \ + S(setreuid, NeedsBigProcessLock::Yes) \ + S(setresuid, NeedsBigProcessLock::Yes) \ + S(setresgid, NeedsBigProcessLock::Yes) \ + S(alarm, NeedsBigProcessLock::Yes) \ + S(fstat, NeedsBigProcessLock::Yes) \ + S(access, NeedsBigProcessLock::Yes) \ + S(fcntl, NeedsBigProcessLock::Yes) \ + S(ioctl, NeedsBigProcessLock::Yes) \ + S(mkdir, NeedsBigProcessLock::Yes) \ + S(times, NeedsBigProcessLock::Yes) \ + S(utime, NeedsBigProcessLock::Yes) \ + S(sync, NeedsBigProcessLock::Yes) \ + S(ptsname, NeedsBigProcessLock::Yes) \ + S(select, NeedsBigProcessLock::Yes) \ + S(unlink, NeedsBigProcessLock::Yes) \ + S(poll, NeedsBigProcessLock::Yes) \ + S(rmdir, NeedsBigProcessLock::Yes) \ + S(chmod, NeedsBigProcessLock::Yes) \ + S(socket, NeedsBigProcessLock::Yes) \ + S(bind, NeedsBigProcessLock::Yes) \ + S(accept4, NeedsBigProcessLock::Yes) \ + S(listen, NeedsBigProcessLock::Yes) \ + S(connect, NeedsBigProcessLock::Yes) \ + S(link, NeedsBigProcessLock::Yes) \ + S(chown, NeedsBigProcessLock::Yes) \ + S(fchmod, NeedsBigProcessLock::Yes) \ + S(symlink, NeedsBigProcessLock::Yes) \ + S(sendmsg, NeedsBigProcessLock::Yes) \ + S(recvmsg, NeedsBigProcessLock::Yes) \ + S(getsockopt, NeedsBigProcessLock::Yes) \ + S(setsockopt, NeedsBigProcessLock::Yes) \ + S(create_thread, NeedsBigProcessLock::Yes) \ + S(gettid, NeedsBigProcessLock::Yes) \ + S(rename, NeedsBigProcessLock::Yes) \ + S(ftruncate, NeedsBigProcessLock::Yes) \ + S(exit_thread, NeedsBigProcessLock::Yes) \ + S(mknod, NeedsBigProcessLock::Yes) \ + S(writev, NeedsBigProcessLock::Yes) \ + S(beep, NeedsBigProcessLock::Yes) \ + S(getsockname, NeedsBigProcessLock::Yes) \ + S(getpeername, NeedsBigProcessLock::Yes) \ + S(socketpair, NeedsBigProcessLock::Yes) \ + S(sched_setparam, NeedsBigProcessLock::Yes) \ + S(sched_getparam, NeedsBigProcessLock::Yes) \ + S(fchown, NeedsBigProcessLock::Yes) \ + S(halt, NeedsBigProcessLock::Yes) \ + S(reboot, NeedsBigProcessLock::Yes) \ + S(mount, NeedsBigProcessLock::Yes) \ + S(umount, NeedsBigProcessLock::Yes) \ + S(dump_backtrace, NeedsBigProcessLock::Yes) \ + S(dbgputch, NeedsBigProcessLock::Yes) \ + S(dbgputstr, NeedsBigProcessLock::Yes) \ + S(create_inode_watcher, NeedsBigProcessLock::Yes) \ + S(inode_watcher_add_watch, NeedsBigProcessLock::Yes) \ + S(inode_watcher_remove_watch, NeedsBigProcessLock::Yes) \ + S(mprotect, NeedsBigProcessLock::Yes) \ + S(realpath, NeedsBigProcessLock::Yes) \ + S(get_process_name, NeedsBigProcessLock::Yes) \ + S(fchdir, NeedsBigProcessLock::Yes) \ + S(getrandom, NeedsBigProcessLock::Yes) \ + S(getkeymap, NeedsBigProcessLock::Yes) \ + S(setkeymap, NeedsBigProcessLock::Yes) \ + S(clock_gettime, NeedsBigProcessLock::Yes) \ + S(clock_settime, NeedsBigProcessLock::Yes) \ + S(clock_nanosleep, NeedsBigProcessLock::Yes) \ + S(join_thread, NeedsBigProcessLock::Yes) \ + S(module_load, NeedsBigProcessLock::Yes) \ + S(module_unload, NeedsBigProcessLock::Yes) \ + S(detach_thread, NeedsBigProcessLock::Yes) \ + S(set_thread_name, NeedsBigProcessLock::Yes) \ + S(get_thread_name, NeedsBigProcessLock::Yes) \ + S(madvise, NeedsBigProcessLock::Yes) \ + S(purge, NeedsBigProcessLock::Yes) \ + S(profiling_enable, NeedsBigProcessLock::Yes) \ + S(profiling_disable, NeedsBigProcessLock::Yes) \ + S(profiling_free_buffer, NeedsBigProcessLock::Yes) \ + S(futex, NeedsBigProcessLock::Yes) \ + S(chroot, NeedsBigProcessLock::Yes) \ + S(pledge, NeedsBigProcessLock::Yes) \ + S(unveil, NeedsBigProcessLock::Yes) \ + S(perf_event, NeedsBigProcessLock::Yes) \ + S(shutdown, NeedsBigProcessLock::Yes) \ + S(get_stack_bounds, NeedsBigProcessLock::Yes) \ + S(ptrace, NeedsBigProcessLock::Yes) \ + S(sendfd, NeedsBigProcessLock::Yes) \ + S(recvfd, NeedsBigProcessLock::Yes) \ + S(sysconf, NeedsBigProcessLock::Yes) \ + S(set_process_name, NeedsBigProcessLock::Yes) \ + S(disown, NeedsBigProcessLock::Yes) \ + S(adjtime, NeedsBigProcessLock::Yes) \ + S(allocate_tls, NeedsBigProcessLock::Yes) \ + S(prctl, NeedsBigProcessLock::Yes) \ + S(mremap, NeedsBigProcessLock::Yes) \ + S(set_coredump_metadata, NeedsBigProcessLock::Yes) \ + S(anon_create, NeedsBigProcessLock::Yes) \ + S(msyscall, NeedsBigProcessLock::Yes) \ + S(readv, NeedsBigProcessLock::Yes) \ + S(emuctl, NeedsBigProcessLock::Yes) \ + S(statvfs, NeedsBigProcessLock::Yes) \ + S(fstatvfs, NeedsBigProcessLock::Yes) \ + S(kill_thread, NeedsBigProcessLock::Yes) namespace Syscall { enum Function { #undef __ENUMERATE_SYSCALL -#define __ENUMERATE_SYSCALL(x) SC_##x, +#define __ENUMERATE_SYSCALL(sys_call, needs_lock) SC_##sys_call, ENUMERATE_SYSCALLS(__ENUMERATE_SYSCALL) #undef __ENUMERATE_SYSCALL __Count @@ -196,9 +201,9 @@ constexpr const char* to_string(Function function) { switch (function) { #undef __ENUMERATE_SYSCALL -#define __ENUMERATE_SYSCALL(x) \ - case SC_##x: \ - return #x; +#define __ENUMERATE_SYSCALL(sys_call, needs_lock) \ + case SC_##sys_call: \ + return #sys_call; ENUMERATE_SYSCALLS(__ENUMERATE_SYSCALL) #undef __ENUMERATE_SYSCALL default: @@ -522,7 +527,7 @@ inline uintptr_t invoke(Function function, T1 arg1, T2 arg2, T3 arg3) } #undef __ENUMERATE_SYSCALL -#define __ENUMERATE_SYSCALL(x) using Syscall::SC_##x; +#define __ENUMERATE_SYSCALL(sys_call, needs_lock) using Syscall::SC_##sys_call; ENUMERATE_SYSCALLS(__ENUMERATE_SYSCALL) #undef __ENUMERATE_SYSCALL diff --git a/Kernel/Process.h b/Kernel/Process.h index dc2bd5aab0..662c46a8c5 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -882,6 +882,12 @@ inline ProcessID Thread::pid() const } while (0) } +#define VERIFY_PROCESS_BIG_LOCK_ACQUIRED(process) \ + VERIFY(process->big_lock().own_lock()); + +#define VERIFY_NO_PROCESS_BIG_LOCK(process) \ + VERIFY(!process->big_lock().own_lock()); + inline static String copy_string_from_user(const Kernel::Syscall::StringArgument& string) { return copy_string_from_user(string.characters, string.length); diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index 0374823953..4f37b67383 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -90,8 +90,13 @@ UNMAP_AFTER_INIT void initialize() #pragma GCC diagnostic ignored "-Wcast-function-type" typedef KResultOr (Process::*Handler)(FlatPtr, FlatPtr, FlatPtr); typedef KResultOr (Process::*HandlerWithRegisterState)(RegisterState&); -#define __ENUMERATE_SYSCALL(x) reinterpret_cast(&Process::sys$##x), -static const Handler s_syscall_table[] = { +struct HandlerMetadata { + Handler handler; + NeedsBigProcessLock needs_lock; +}; + +#define __ENUMERATE_SYSCALL(sys_call, needs_lock) { reinterpret_cast(&Process::sys$##sys_call), needs_lock }, +static const HandlerMetadata s_syscall_table[] = { ENUMERATE_SYSCALLS(__ENUMERATE_SYSCALL) }; #undef __ENUMERATE_SYSCALL @@ -126,7 +131,7 @@ KResultOr handle(RegisterState& regs, FlatPtr function, FlatPtr arg1, F if (function == SC_fork || function == SC_sigreturn) { // These syscalls want the RegisterState& rather than individual parameters. - auto handler = (HandlerWithRegisterState)s_syscall_table[function]; + auto handler = (HandlerWithRegisterState)s_syscall_table[function].handler; return (process.*(handler))(regs); } @@ -135,12 +140,12 @@ KResultOr handle(RegisterState& regs, FlatPtr function, FlatPtr arg1, F return ENOSYS; } - if (s_syscall_table[function] == nullptr) { + if (s_syscall_table[function].handler == nullptr) { dbgln("Null syscall {} requested, you probably need to rebuild this program!", function); return ENOSYS; } - return (process.*(s_syscall_table[function]))(arg1, arg2, arg3); + return (process.*(s_syscall_table[function].handler))(arg1, arg2, arg3); } }