mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 10:18:11 +00:00
Kernel: Handle promise violations in the syscall handler
Previously we would crash the process immediately when a promise violation was found during a syscall. This is error prone, as we don't unwind the stack. This means that in certain cases we can leak resources, like an OwnPtr / RefPtr tracked on the stack. Or even leak a lock acquired in a ScopeLockLocker. To remedy this situation we move the promise violation handling to the syscall handler, right before we return to user space. This allows the code to follow the normal unwind path, and grantees there is no longer any cleanup that needs to occur. The Process::require_promise() and Process::require_no_promises() functions were modified to return ErrorOr<void> so we enforce that the errors are always propagated by the caller.
This commit is contained in:
parent
c444a3fc9e
commit
54b9a4ec1e
66 changed files with 156 additions and 148 deletions
|
@ -29,7 +29,7 @@ NonnullRefPtr<FramebufferDevice> FramebufferDevice::create(const GenericGraphics
|
||||||
|
|
||||||
ErrorOr<Memory::Region*> FramebufferDevice::mmap(Process& process, OpenFileDescription&, Memory::VirtualRange const& range, u64 offset, int prot, bool shared)
|
ErrorOr<Memory::Region*> FramebufferDevice::mmap(Process& process, OpenFileDescription&, Memory::VirtualRange const& range, u64 offset, int prot, bool shared)
|
||||||
{
|
{
|
||||||
process.require_promise(Pledge::video);
|
TRY(process.require_promise(Pledge::video));
|
||||||
SpinlockLocker lock(m_activation_lock);
|
SpinlockLocker lock(m_activation_lock);
|
||||||
if (!shared)
|
if (!shared)
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
|
|
|
@ -33,7 +33,7 @@ ErrorOr<void> GenericFramebufferDevice::verify_head_index(int head_index) const
|
||||||
|
|
||||||
ErrorOr<void> GenericFramebufferDevice::ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg)
|
ErrorOr<void> GenericFramebufferDevice::ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg)
|
||||||
{
|
{
|
||||||
Process::current().require_promise(Pledge::video);
|
TRY(Process::current().require_promise(Pledge::video));
|
||||||
switch (request) {
|
switch (request) {
|
||||||
case FB_IOCTL_GET_PROPERTIES: {
|
case FB_IOCTL_GET_PROPERTIES: {
|
||||||
auto user_properties = static_ptr_cast<FBProperties*>(arg);
|
auto user_properties = static_ptr_cast<FBProperties*>(arg);
|
||||||
|
|
|
@ -257,7 +257,7 @@ void FramebufferDevice::set_buffer(int buffer_index)
|
||||||
|
|
||||||
ErrorOr<Memory::Region*> FramebufferDevice::mmap(Process& process, OpenFileDescription&, Memory::VirtualRange const& range, u64 offset, int prot, bool shared)
|
ErrorOr<Memory::Region*> FramebufferDevice::mmap(Process& process, OpenFileDescription&, Memory::VirtualRange const& range, u64 offset, int prot, bool shared)
|
||||||
{
|
{
|
||||||
process.require_promise(Pledge::video);
|
TRY(process.require_promise(Pledge::video));
|
||||||
if (!shared)
|
if (!shared)
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
if (offset != 0 || !m_framebuffer)
|
if (offset != 0 || !m_framebuffer)
|
||||||
|
|
|
@ -607,7 +607,7 @@ ErrorOr<void> IPv4Socket::getsockopt(OpenFileDescription& description, int level
|
||||||
|
|
||||||
ErrorOr<void> IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg)
|
ErrorOr<void> IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg)
|
||||||
{
|
{
|
||||||
Process::current().require_promise(Pledge::inet);
|
TRY(Process::current().require_promise(Pledge::inet));
|
||||||
|
|
||||||
auto ioctl_route = [request, arg]() -> ErrorOr<void> {
|
auto ioctl_route = [request, arg]() -> ErrorOr<void> {
|
||||||
auto user_route = static_ptr_cast<rtentry*>(arg);
|
auto user_route = static_ptr_cast<rtentry*>(arg);
|
||||||
|
|
|
@ -863,26 +863,25 @@ static constexpr StringView to_string(Pledge promise)
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process::require_no_promises() const
|
ErrorOr<void> Process::require_no_promises() const
|
||||||
{
|
{
|
||||||
if (!has_promises())
|
if (!has_promises())
|
||||||
return;
|
return {};
|
||||||
dbgln("Has made a promise");
|
dbgln("Has made a promise");
|
||||||
Process::current().crash(SIGABRT, 0);
|
return EPROMISEVIOLATION;
|
||||||
VERIFY_NOT_REACHED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process::require_promise(Pledge promise)
|
ErrorOr<void> Process::require_promise(Pledge promise)
|
||||||
{
|
{
|
||||||
if (!has_promises())
|
if (!has_promises())
|
||||||
return;
|
return {};
|
||||||
|
|
||||||
if (has_promised(promise))
|
if (has_promised(promise))
|
||||||
return;
|
return {};
|
||||||
|
|
||||||
dbgln("Has not pledged {}", to_string(promise));
|
dbgln("Has not pledged {}", to_string(promise));
|
||||||
(void)try_set_coredump_property("pledge_violation"sv, to_string(promise));
|
(void)try_set_coredump_property("pledge_violation"sv, to_string(promise));
|
||||||
crash(SIGABRT, 0);
|
return EPROMISEVIOLATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -508,8 +508,8 @@ public:
|
||||||
|
|
||||||
VirtualAddress signal_trampoline() const { return m_protected_values.signal_trampoline; }
|
VirtualAddress signal_trampoline() const { return m_protected_values.signal_trampoline; }
|
||||||
|
|
||||||
void require_promise(Pledge);
|
ErrorOr<void> require_promise(Pledge);
|
||||||
void require_no_promises() const;
|
ErrorOr<void> require_no_promises() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class MemoryManager;
|
friend class MemoryManager;
|
||||||
|
|
|
@ -234,6 +234,10 @@ NEVER_INLINE void syscall_handler(TrapFrame* trap)
|
||||||
// Check if we're supposed to return to userspace or just die.
|
// Check if we're supposed to return to userspace or just die.
|
||||||
current_thread->die_if_needed();
|
current_thread->die_if_needed();
|
||||||
|
|
||||||
|
// Crash any processes which have commited a promise violation during syscall handling.
|
||||||
|
if (result.is_error() && result.error().code() == EPROMISEVIOLATION)
|
||||||
|
process.crash(SIGABRT, 0);
|
||||||
|
|
||||||
VERIFY(!g_scheduler_lock.is_locked_by_current_processor());
|
VERIFY(!g_scheduler_lock.is_locked_by_current_processor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$access(Userspace<const char*> user_path, size_t path_length, int mode)
|
ErrorOr<FlatPtr> Process::sys$access(Userspace<const char*> user_path, size_t path_length, int mode)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::rpath);
|
TRY(require_promise(Pledge::rpath));
|
||||||
auto path = TRY(get_syscall_path_argument(user_path, path_length));
|
auto path = TRY(get_syscall_path_argument(user_path, path_length));
|
||||||
TRY(VirtualFileSystem::the().access(path->view(), mode, current_directory()));
|
TRY(VirtualFileSystem::the().access(path->view(), mode, current_directory()));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$alarm(unsigned seconds)
|
ErrorOr<FlatPtr> Process::sys$alarm(unsigned seconds)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
unsigned previous_alarm_remaining = 0;
|
unsigned previous_alarm_remaining = 0;
|
||||||
if (m_alarm_timer) {
|
if (m_alarm_timer) {
|
||||||
bool was_in_use = false;
|
bool was_in_use = false;
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$anon_create(size_t size, int options)
|
ErrorOr<FlatPtr> Process::sys$anon_create(size_t size, int options)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
|
|
||||||
if (!size)
|
if (!size)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$chdir(Userspace<const char*> user_path, size_t path_length)
|
ErrorOr<FlatPtr> Process::sys$chdir(Userspace<const char*> user_path, size_t path_length)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::rpath);
|
TRY(require_promise(Pledge::rpath));
|
||||||
auto path = TRY(get_syscall_path_argument(user_path, path_length));
|
auto path = TRY(get_syscall_path_argument(user_path, path_length));
|
||||||
m_cwd = TRY(VirtualFileSystem::the().open_directory(path->view(), current_directory()));
|
m_cwd = TRY(VirtualFileSystem::the().open_directory(path->view(), current_directory()));
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -22,7 +22,7 @@ ErrorOr<FlatPtr> Process::sys$chdir(Userspace<const char*> user_path, size_t pat
|
||||||
ErrorOr<FlatPtr> Process::sys$fchdir(int fd)
|
ErrorOr<FlatPtr> Process::sys$fchdir(int fd)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
auto description = TRY(fds().open_file_description(fd));
|
auto description = TRY(fds().open_file_description(fd));
|
||||||
if (!description->is_directory())
|
if (!description->is_directory())
|
||||||
return ENOTDIR;
|
return ENOTDIR;
|
||||||
|
@ -35,7 +35,7 @@ ErrorOr<FlatPtr> Process::sys$fchdir(int fd)
|
||||||
ErrorOr<FlatPtr> Process::sys$getcwd(Userspace<char*> buffer, size_t size)
|
ErrorOr<FlatPtr> Process::sys$getcwd(Userspace<char*> buffer, size_t size)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::rpath);
|
TRY(require_promise(Pledge::rpath));
|
||||||
|
|
||||||
if (size > NumericLimits<ssize_t>::max())
|
if (size > NumericLimits<ssize_t>::max())
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$chmod(Userspace<const char*> user_path, size_t path_length, mode_t mode)
|
ErrorOr<FlatPtr> Process::sys$chmod(Userspace<const char*> user_path, size_t path_length, mode_t mode)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::fattr);
|
TRY(require_promise(Pledge::fattr));
|
||||||
auto path = TRY(get_syscall_path_argument(user_path, path_length));
|
auto path = TRY(get_syscall_path_argument(user_path, path_length));
|
||||||
TRY(VirtualFileSystem::the().chmod(path->view(), mode, current_directory()));
|
TRY(VirtualFileSystem::the().chmod(path->view(), mode, current_directory()));
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -22,7 +22,7 @@ ErrorOr<FlatPtr> Process::sys$chmod(Userspace<const char*> user_path, size_t pat
|
||||||
ErrorOr<FlatPtr> Process::sys$fchmod(int fd, mode_t mode)
|
ErrorOr<FlatPtr> Process::sys$fchmod(int fd, mode_t mode)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::fattr);
|
TRY(require_promise(Pledge::fattr));
|
||||||
auto description = TRY(fds().open_file_description(fd));
|
auto description = TRY(fds().open_file_description(fd));
|
||||||
TRY(description->chmod(mode));
|
TRY(description->chmod(mode));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$fchown(int fd, UserID uid, GroupID gid)
|
ErrorOr<FlatPtr> Process::sys$fchown(int fd, UserID uid, GroupID gid)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::chown);
|
TRY(require_promise(Pledge::chown));
|
||||||
auto description = TRY(fds().open_file_description(fd));
|
auto description = TRY(fds().open_file_description(fd));
|
||||||
TRY(description->chown(uid, gid));
|
TRY(description->chown(uid, gid));
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -21,7 +21,7 @@ ErrorOr<FlatPtr> Process::sys$fchown(int fd, UserID uid, GroupID gid)
|
||||||
ErrorOr<FlatPtr> Process::sys$chown(Userspace<const Syscall::SC_chown_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$chown(Userspace<const Syscall::SC_chown_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::chown);
|
TRY(require_promise(Pledge::chown));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
auto path = TRY(get_syscall_path_argument(params.path));
|
auto path = TRY(get_syscall_path_argument(params.path));
|
||||||
TRY(VirtualFileSystem::the().chown(path->view(), params.uid, params.gid, current_directory()));
|
TRY(VirtualFileSystem::the().chown(path->view(), params.uid, params.gid, current_directory()));
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$map_time_page()
|
ErrorOr<FlatPtr> Process::sys$map_time_page()
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
|
|
||||||
auto& vmobject = TimeManagement::the().time_page_vmobject();
|
auto& vmobject = TimeManagement::the().time_page_vmobject();
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ ErrorOr<FlatPtr> Process::sys$map_time_page()
|
||||||
ErrorOr<FlatPtr> Process::sys$clock_gettime(clockid_t clock_id, Userspace<timespec*> user_ts)
|
ErrorOr<FlatPtr> Process::sys$clock_gettime(clockid_t clock_id, Userspace<timespec*> user_ts)
|
||||||
{
|
{
|
||||||
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
|
|
||||||
if (!TimeManagement::is_valid_clock_id(clock_id))
|
if (!TimeManagement::is_valid_clock_id(clock_id))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
@ -38,7 +38,7 @@ ErrorOr<FlatPtr> Process::sys$clock_gettime(clockid_t clock_id, Userspace<timesp
|
||||||
ErrorOr<FlatPtr> Process::sys$clock_settime(clockid_t clock_id, Userspace<const timespec*> user_ts)
|
ErrorOr<FlatPtr> Process::sys$clock_settime(clockid_t clock_id, Userspace<const timespec*> user_ts)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::settime);
|
TRY(require_promise(Pledge::settime));
|
||||||
|
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return EPERM;
|
return EPERM;
|
||||||
|
@ -58,7 +58,7 @@ ErrorOr<FlatPtr> Process::sys$clock_settime(clockid_t clock_id, Userspace<const
|
||||||
ErrorOr<FlatPtr> Process::sys$clock_nanosleep(Userspace<const Syscall::SC_clock_nanosleep_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$clock_nanosleep(Userspace<const Syscall::SC_clock_nanosleep_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
|
|
||||||
auto requested_sleep = TRY(copy_time_from_user(params.requested_sleep));
|
auto requested_sleep = TRY(copy_time_from_user(params.requested_sleep));
|
||||||
|
@ -105,7 +105,7 @@ ErrorOr<FlatPtr> Process::sys$adjtime(Userspace<const timeval*> user_delta, User
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user_delta) {
|
if (user_delta) {
|
||||||
require_promise(Pledge::settime);
|
TRY(require_promise(Pledge::settime));
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return EPERM;
|
return EPERM;
|
||||||
auto delta = TRY(copy_time_from_user(user_delta));
|
auto delta = TRY(copy_time_from_user(user_delta));
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$disown(ProcessID pid)
|
ErrorOr<FlatPtr> Process::sys$disown(ProcessID pid)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::proc);
|
TRY(require_promise(Pledge::proc));
|
||||||
auto process = Process::from_pid(pid);
|
auto process = Process::from_pid(pid);
|
||||||
if (!process)
|
if (!process)
|
||||||
return ESRCH;
|
return ESRCH;
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$dup2(int old_fd, int new_fd)
|
ErrorOr<FlatPtr> Process::sys$dup2(int old_fd, int new_fd)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
auto description = TRY(fds().open_file_description(old_fd));
|
auto description = TRY(fds().open_file_description(old_fd));
|
||||||
if (old_fd == new_fd)
|
if (old_fd == new_fd)
|
||||||
return new_fd;
|
return new_fd;
|
||||||
|
|
|
@ -859,7 +859,7 @@ ErrorOr<void> Process::exec(NonnullOwnPtr<KString> path, NonnullOwnPtrVector<KSt
|
||||||
ErrorOr<FlatPtr> Process::sys$execve(Userspace<const Syscall::SC_execve_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$execve(Userspace<const Syscall::SC_execve_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::exec);
|
TRY(require_promise(Pledge::exec));
|
||||||
|
|
||||||
// NOTE: Be extremely careful with allocating any kernel memory in exec().
|
// NOTE: Be extremely careful with allocating any kernel memory in exec().
|
||||||
// On success, the kernel stack will be lost.
|
// On success, the kernel stack will be lost.
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$fcntl(int fd, int cmd, u32 arg)
|
ErrorOr<FlatPtr> Process::sys$fcntl(int fd, int cmd, u32 arg)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
dbgln_if(IO_DEBUG, "sys$fcntl: fd={}, cmd={}, arg={}", fd, cmd, arg);
|
dbgln_if(IO_DEBUG, "sys$fcntl: fd={}, cmd={}, arg={}", fd, cmd, arg);
|
||||||
auto description = TRY(fds().open_file_description(fd));
|
auto description = TRY(fds().open_file_description(fd));
|
||||||
// NOTE: The FD flags are not shared between OpenFileDescription objects.
|
// NOTE: The FD flags are not shared between OpenFileDescription objects.
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$fork(RegisterState& regs)
|
ErrorOr<FlatPtr> Process::sys$fork(RegisterState& regs)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::proc);
|
TRY(require_promise(Pledge::proc));
|
||||||
RefPtr<Thread> child_first_thread;
|
RefPtr<Thread> child_first_thread;
|
||||||
auto child_name = TRY(m_name->try_clone());
|
auto child_name = TRY(m_name->try_clone());
|
||||||
auto child = TRY(Process::try_create(child_first_thread, move(child_name), uid(), gid(), pid(), m_is_kernel_process, m_cwd, m_executable, m_tty, this));
|
auto child = TRY(Process::try_create(child_first_thread, move(child_name), uid(), gid(), pid(), m_is_kernel_process, m_cwd, m_executable, m_tty, this));
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$fsync(int fd)
|
ErrorOr<FlatPtr> Process::sys$fsync(int fd)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
auto description = TRY(fds().open_file_description(fd));
|
auto description = TRY(fds().open_file_description(fd));
|
||||||
TRY(description->sync());
|
TRY(description->sync());
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$ftruncate(int fd, Userspace<off_t const*> userspace_length)
|
ErrorOr<FlatPtr> Process::sys$ftruncate(int fd, Userspace<off_t const*> userspace_length)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
auto length = TRY(copy_typed_from_user(userspace_length));
|
auto length = TRY(copy_typed_from_user(userspace_length));
|
||||||
if (length < 0)
|
if (length < 0)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$get_dir_entries(int fd, Userspace<void*> user_buffer, size_t user_size)
|
ErrorOr<FlatPtr> Process::sys$get_dir_entries(int fd, Userspace<void*> user_buffer, size_t user_size)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
if (user_size > NumericLimits<ssize_t>::max())
|
if (user_size > NumericLimits<ssize_t>::max())
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
auto description = TRY(fds().open_file_description(fd));
|
auto description = TRY(fds().open_file_description(fd));
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$getrandom(Userspace<void*> buffer, size_t buffer_size, [[maybe_unused]] unsigned flags)
|
ErrorOr<FlatPtr> Process::sys$getrandom(Userspace<void*> buffer, size_t buffer_size, [[maybe_unused]] unsigned flags)
|
||||||
{
|
{
|
||||||
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
if (buffer_size > NumericLimits<ssize_t>::max())
|
if (buffer_size > NumericLimits<ssize_t>::max())
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
|
|
|
@ -11,35 +11,35 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$getuid()
|
ErrorOr<FlatPtr> Process::sys$getuid()
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
return uid().value();
|
return uid().value();
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<FlatPtr> Process::sys$getgid()
|
ErrorOr<FlatPtr> Process::sys$getgid()
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
return gid().value();
|
return gid().value();
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<FlatPtr> Process::sys$geteuid()
|
ErrorOr<FlatPtr> Process::sys$geteuid()
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
return euid().value();
|
return euid().value();
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<FlatPtr> Process::sys$getegid()
|
ErrorOr<FlatPtr> Process::sys$getegid()
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
return egid().value();
|
return egid().value();
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<FlatPtr> Process::sys$getresuid(Userspace<UserID*> ruid, Userspace<UserID*> euid, Userspace<UserID*> suid)
|
ErrorOr<FlatPtr> Process::sys$getresuid(Userspace<UserID*> ruid, Userspace<UserID*> euid, Userspace<UserID*> suid)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
TRY(copy_to_user(ruid, &m_protected_values.uid));
|
TRY(copy_to_user(ruid, &m_protected_values.uid));
|
||||||
TRY(copy_to_user(euid, &m_protected_values.euid));
|
TRY(copy_to_user(euid, &m_protected_values.euid));
|
||||||
TRY(copy_to_user(suid, &m_protected_values.suid));
|
TRY(copy_to_user(suid, &m_protected_values.suid));
|
||||||
|
@ -49,7 +49,7 @@ ErrorOr<FlatPtr> Process::sys$getresuid(Userspace<UserID*> ruid, Userspace<UserI
|
||||||
ErrorOr<FlatPtr> Process::sys$getresgid(Userspace<GroupID*> rgid, Userspace<GroupID*> egid, Userspace<GroupID*> sgid)
|
ErrorOr<FlatPtr> Process::sys$getresgid(Userspace<GroupID*> rgid, Userspace<GroupID*> egid, Userspace<GroupID*> sgid)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
TRY(copy_to_user(rgid, &m_protected_values.gid));
|
TRY(copy_to_user(rgid, &m_protected_values.gid));
|
||||||
TRY(copy_to_user(egid, &m_protected_values.egid));
|
TRY(copy_to_user(egid, &m_protected_values.egid));
|
||||||
TRY(copy_to_user(sgid, &m_protected_values.sgid));
|
TRY(copy_to_user(sgid, &m_protected_values.sgid));
|
||||||
|
@ -59,7 +59,7 @@ ErrorOr<FlatPtr> Process::sys$getresgid(Userspace<GroupID*> rgid, Userspace<Grou
|
||||||
ErrorOr<FlatPtr> Process::sys$getgroups(size_t count, Userspace<gid_t*> user_gids)
|
ErrorOr<FlatPtr> Process::sys$getgroups(size_t count, Userspace<gid_t*> user_gids)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
if (!count)
|
if (!count)
|
||||||
return extra_gids().size();
|
return extra_gids().size();
|
||||||
if (count != extra_gids().size())
|
if (count != extra_gids().size())
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$gethostname(Userspace<char*> buffer, size_t size)
|
ErrorOr<FlatPtr> Process::sys$gethostname(Userspace<char*> buffer, size_t size)
|
||||||
{
|
{
|
||||||
VERIFY_NO_PROCESS_BIG_LOCK(this)
|
VERIFY_NO_PROCESS_BIG_LOCK(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
if (size > NumericLimits<ssize_t>::max())
|
if (size > NumericLimits<ssize_t>::max())
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
return hostname().with_shared([&](const auto& name) -> ErrorOr<FlatPtr> {
|
return hostname().with_shared([&](const auto& name) -> ErrorOr<FlatPtr> {
|
||||||
|
@ -25,7 +25,7 @@ ErrorOr<FlatPtr> Process::sys$gethostname(Userspace<char*> buffer, size_t size)
|
||||||
ErrorOr<FlatPtr> Process::sys$sethostname(Userspace<const char*> buffer, size_t length)
|
ErrorOr<FlatPtr> Process::sys$sethostname(Userspace<const char*> buffer, size_t length)
|
||||||
{
|
{
|
||||||
VERIFY_NO_PROCESS_BIG_LOCK(this)
|
VERIFY_NO_PROCESS_BIG_LOCK(this)
|
||||||
require_no_promises();
|
TRY(require_no_promises());
|
||||||
|
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return EPERM;
|
return EPERM;
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$create_inode_watcher(u32 flags)
|
ErrorOr<FlatPtr> Process::sys$create_inode_watcher(u32 flags)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::rpath);
|
TRY(require_promise(Pledge::rpath));
|
||||||
|
|
||||||
auto fd_allocation = TRY(m_fds.allocate());
|
auto fd_allocation = TRY(m_fds.allocate());
|
||||||
auto watcher = TRY(InodeWatcher::try_create());
|
auto watcher = TRY(InodeWatcher::try_create());
|
||||||
|
@ -37,7 +37,7 @@ ErrorOr<FlatPtr> Process::sys$create_inode_watcher(u32 flags)
|
||||||
ErrorOr<FlatPtr> Process::sys$inode_watcher_add_watch(Userspace<const Syscall::SC_inode_watcher_add_watch_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$inode_watcher_add_watch(Userspace<const Syscall::SC_inode_watcher_add_watch_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::rpath);
|
TRY(require_promise(Pledge::rpath));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
|
|
||||||
auto description = TRY(fds().open_file_description(params.fd));
|
auto description = TRY(fds().open_file_description(params.fd));
|
||||||
|
|
|
@ -14,7 +14,7 @@ constexpr size_t map_name_max_size = 50;
|
||||||
ErrorOr<FlatPtr> Process::sys$setkeymap(Userspace<const Syscall::SC_setkeymap_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$setkeymap(Userspace<const Syscall::SC_setkeymap_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
require_promise(Pledge::setkeymap);
|
TRY(require_promise(Pledge::setkeymap));
|
||||||
|
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return EPERM;
|
return EPERM;
|
||||||
|
@ -40,7 +40,7 @@ ErrorOr<FlatPtr> Process::sys$setkeymap(Userspace<const Syscall::SC_setkeymap_pa
|
||||||
ErrorOr<FlatPtr> Process::sys$getkeymap(Userspace<const Syscall::SC_getkeymap_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$getkeymap(Userspace<const Syscall::SC_getkeymap_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
||||||
require_promise(Pledge::getkeymap);
|
TRY(require_promise(Pledge::getkeymap));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
|
|
||||||
String keymap_name = HIDManagement::the().keymap_name();
|
String keymap_name = HIDManagement::the().keymap_name();
|
||||||
|
|
|
@ -99,9 +99,9 @@ ErrorOr<FlatPtr> Process::sys$kill(pid_t pid_or_pgid, int signal)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
if (pid_or_pgid == pid().value())
|
if (pid_or_pgid == pid().value())
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
else
|
else
|
||||||
require_promise(Pledge::proc);
|
TRY(require_promise(Pledge::proc));
|
||||||
|
|
||||||
if (signal < 0 || signal >= 32)
|
if (signal < 0 || signal >= 32)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
@ -130,7 +130,7 @@ ErrorOr<FlatPtr> Process::sys$kill(pid_t pid_or_pgid, int signal)
|
||||||
ErrorOr<FlatPtr> Process::sys$killpg(pid_t pgrp, int signum)
|
ErrorOr<FlatPtr> Process::sys$killpg(pid_t pgrp, int signum)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::proc);
|
TRY(require_promise(Pledge::proc));
|
||||||
if (signum < 1 || signum >= 32)
|
if (signum < 1 || signum >= 32)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
if (pgrp < 0)
|
if (pgrp < 0)
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$link(Userspace<const Syscall::SC_link_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$link(Userspace<const Syscall::SC_link_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::cpath);
|
TRY(require_promise(Pledge::cpath));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
auto old_path = TRY(try_copy_kstring_from_user(params.old_path));
|
auto old_path = TRY(try_copy_kstring_from_user(params.old_path));
|
||||||
auto new_path = TRY(try_copy_kstring_from_user(params.new_path));
|
auto new_path = TRY(try_copy_kstring_from_user(params.new_path));
|
||||||
|
@ -24,7 +24,7 @@ ErrorOr<FlatPtr> Process::sys$link(Userspace<const Syscall::SC_link_params*> use
|
||||||
ErrorOr<FlatPtr> Process::sys$symlink(Userspace<const Syscall::SC_symlink_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$symlink(Userspace<const Syscall::SC_symlink_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::cpath);
|
TRY(require_promise(Pledge::cpath));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
|
|
||||||
auto target = TRY(get_syscall_path_argument(params.target));
|
auto target = TRY(get_syscall_path_argument(params.target));
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$lseek(int fd, Userspace<off_t*> userspace_offset, int whence)
|
ErrorOr<FlatPtr> Process::sys$lseek(int fd, Userspace<off_t*> userspace_offset, int whence)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
auto description = TRY(fds().open_file_description(fd));
|
auto description = TRY(fds().open_file_description(fd));
|
||||||
off_t offset;
|
off_t offset;
|
||||||
TRY(copy_from_user(&offset, userspace_offset));
|
TRY(copy_from_user(&offset, userspace_offset));
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$mkdir(Userspace<const char*> user_path, size_t path_length, mode_t mode)
|
ErrorOr<FlatPtr> Process::sys$mkdir(Userspace<const char*> user_path, size_t path_length, mode_t mode)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::cpath);
|
TRY(require_promise(Pledge::cpath));
|
||||||
auto path = TRY(get_syscall_path_argument(user_path, path_length));
|
auto path = TRY(get_syscall_path_argument(user_path, path_length));
|
||||||
TRY(VirtualFileSystem::the().mkdir(path->view(), mode & ~umask(), current_directory()));
|
TRY(VirtualFileSystem::the().mkdir(path->view(), mode & ~umask(), current_directory()));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$mknod(Userspace<const Syscall::SC_mknod_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$mknod(Userspace<const Syscall::SC_mknod_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::dpath);
|
TRY(require_promise(Pledge::dpath));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
|
|
||||||
if (!is_superuser() && !is_regular_file(params.mode) && !is_fifo(params.mode) && !is_socket(params.mode))
|
if (!is_superuser() && !is_regular_file(params.mode) && !is_fifo(params.mode) && !is_socket(params.mode))
|
||||||
|
|
|
@ -120,7 +120,7 @@ static bool validate_inode_mmap_prot(const Process& process, int prot, const Ino
|
||||||
ErrorOr<FlatPtr> Process::sys$mmap(Userspace<const Syscall::SC_mmap_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$mmap(Userspace<const Syscall::SC_mmap_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
|
|
||||||
auto addr = (FlatPtr)params.addr;
|
auto addr = (FlatPtr)params.addr;
|
||||||
|
@ -132,11 +132,11 @@ ErrorOr<FlatPtr> Process::sys$mmap(Userspace<const Syscall::SC_mmap_params*> use
|
||||||
auto offset = params.offset;
|
auto offset = params.offset;
|
||||||
|
|
||||||
if (prot & PROT_EXEC) {
|
if (prot & PROT_EXEC) {
|
||||||
require_promise(Pledge::prot_exec);
|
TRY(require_promise(Pledge::prot_exec));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prot & MAP_FIXED || prot & MAP_FIXED_NOREPLACE) {
|
if (prot & MAP_FIXED || prot & MAP_FIXED_NOREPLACE) {
|
||||||
require_promise(Pledge::map_fixed);
|
TRY(require_promise(Pledge::map_fixed));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alignment & ~PAGE_MASK)
|
if (alignment & ~PAGE_MASK)
|
||||||
|
@ -253,10 +253,10 @@ ErrorOr<FlatPtr> Process::sys$mmap(Userspace<const Syscall::SC_mmap_params*> use
|
||||||
ErrorOr<FlatPtr> Process::sys$mprotect(Userspace<void*> addr, size_t size, int prot)
|
ErrorOr<FlatPtr> Process::sys$mprotect(Userspace<void*> addr, size_t size, int prot)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
|
|
||||||
if (prot & PROT_EXEC) {
|
if (prot & PROT_EXEC) {
|
||||||
require_promise(Pledge::prot_exec);
|
TRY(require_promise(Pledge::prot_exec));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto range_to_mprotect = TRY(Memory::expand_range_to_page_boundaries(addr.ptr(), size));
|
auto range_to_mprotect = TRY(Memory::expand_range_to_page_boundaries(addr.ptr(), size));
|
||||||
|
@ -395,7 +395,7 @@ ErrorOr<FlatPtr> Process::sys$mprotect(Userspace<void*> addr, size_t size, int p
|
||||||
ErrorOr<FlatPtr> Process::sys$madvise(Userspace<void*> address, size_t size, int advice)
|
ErrorOr<FlatPtr> Process::sys$madvise(Userspace<void*> address, size_t size, int advice)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
|
|
||||||
auto range_to_madvise = TRY(Memory::expand_range_to_page_boundaries(address.ptr(), size));
|
auto range_to_madvise = TRY(Memory::expand_range_to_page_boundaries(address.ptr(), size));
|
||||||
|
|
||||||
|
@ -426,7 +426,7 @@ ErrorOr<FlatPtr> Process::sys$madvise(Userspace<void*> address, size_t size, int
|
||||||
ErrorOr<FlatPtr> Process::sys$set_mmap_name(Userspace<const Syscall::SC_set_mmap_name_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$set_mmap_name(Userspace<const Syscall::SC_set_mmap_name_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
|
|
||||||
if (params.name.length > PATH_MAX)
|
if (params.name.length > PATH_MAX)
|
||||||
|
@ -450,7 +450,7 @@ ErrorOr<FlatPtr> Process::sys$set_mmap_name(Userspace<const Syscall::SC_set_mmap
|
||||||
ErrorOr<FlatPtr> Process::sys$munmap(Userspace<void*> addr, size_t size)
|
ErrorOr<FlatPtr> Process::sys$munmap(Userspace<void*> addr, size_t size)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
TRY(address_space().unmap_mmap_range(addr.vaddr(), size));
|
TRY(address_space().unmap_mmap_range(addr.vaddr(), size));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -458,7 +458,7 @@ ErrorOr<FlatPtr> Process::sys$munmap(Userspace<void*> addr, size_t size)
|
||||||
ErrorOr<FlatPtr> Process::sys$mremap(Userspace<const Syscall::SC_mremap_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$mremap(Userspace<const Syscall::SC_mremap_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
|
|
||||||
auto old_range = TRY(Memory::expand_range_to_page_boundaries((FlatPtr)params.old_address, params.old_size));
|
auto old_range = TRY(Memory::expand_range_to_page_boundaries((FlatPtr)params.old_address, params.old_size));
|
||||||
|
@ -495,7 +495,7 @@ ErrorOr<FlatPtr> Process::sys$mremap(Userspace<const Syscall::SC_mremap_params*>
|
||||||
ErrorOr<FlatPtr> Process::sys$allocate_tls(Userspace<const char*> initial_data, size_t size)
|
ErrorOr<FlatPtr> Process::sys$allocate_tls(Userspace<const char*> initial_data, size_t size)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
|
|
||||||
if (!size || size % PAGE_SIZE != 0)
|
if (!size || size % PAGE_SIZE != 0)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$mount(Userspace<const Syscall::SC_mount_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$mount(Userspace<const Syscall::SC_mount_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_no_promises();
|
TRY(require_no_promises());
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return EPERM;
|
return EPERM;
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ ErrorOr<FlatPtr> Process::sys$umount(Userspace<const char*> user_mountpoint, siz
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return EPERM;
|
return EPERM;
|
||||||
|
|
||||||
require_no_promises();
|
TRY(require_no_promises());
|
||||||
|
|
||||||
auto mountpoint = TRY(get_syscall_path_argument(user_mountpoint, mountpoint_length));
|
auto mountpoint = TRY(get_syscall_path_argument(user_mountpoint, mountpoint_length));
|
||||||
auto custody = TRY(VirtualFileSystem::the().resolve_path(mountpoint->view(), current_directory()));
|
auto custody = TRY(VirtualFileSystem::the().resolve_path(mountpoint->view(), current_directory()));
|
||||||
|
|
|
@ -27,12 +27,12 @@ ErrorOr<FlatPtr> Process::sys$open(Userspace<const Syscall::SC_open_params*> use
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
if (options & O_WRONLY)
|
if (options & O_WRONLY)
|
||||||
require_promise(Pledge::wpath);
|
TRY(require_promise(Pledge::wpath));
|
||||||
else if (options & O_RDONLY)
|
else if (options & O_RDONLY)
|
||||||
require_promise(Pledge::rpath);
|
TRY(require_promise(Pledge::rpath));
|
||||||
|
|
||||||
if (options & O_CREAT)
|
if (options & O_CREAT)
|
||||||
require_promise(Pledge::cpath);
|
TRY(require_promise(Pledge::cpath));
|
||||||
|
|
||||||
// Ignore everything except permission bits.
|
// Ignore everything except permission bits.
|
||||||
mode &= 0777;
|
mode &= 0777;
|
||||||
|
@ -67,7 +67,7 @@ ErrorOr<FlatPtr> Process::sys$open(Userspace<const Syscall::SC_open_params*> use
|
||||||
ErrorOr<FlatPtr> Process::sys$close(int fd)
|
ErrorOr<FlatPtr> Process::sys$close(int fd)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
auto description = TRY(fds().open_file_description(fd));
|
auto description = TRY(fds().open_file_description(fd));
|
||||||
auto result = description->close();
|
auto result = description->close();
|
||||||
m_fds[fd] = {};
|
m_fds[fd] = {};
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$pipe(int pipefd[2], int flags)
|
ErrorOr<FlatPtr> Process::sys$pipe(int pipefd[2], int flags)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
if (fds().open_count() + 2 > OpenFileDescriptions::max_open())
|
if (fds().open_count() + 2 > OpenFileDescriptions::max_open())
|
||||||
return EMFILE;
|
return EMFILE;
|
||||||
// Reject flags other than O_CLOEXEC, O_NONBLOCK
|
// Reject flags other than O_CLOEXEC, O_NONBLOCK
|
||||||
|
|
|
@ -17,7 +17,7 @@ using BlockFlags = Thread::FileBlocker::BlockFlags;
|
||||||
ErrorOr<FlatPtr> Process::sys$poll(Userspace<const Syscall::SC_poll_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$poll(Userspace<const Syscall::SC_poll_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
|
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
|
|
||||||
|
|
|
@ -12,21 +12,21 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$getpid()
|
ErrorOr<FlatPtr> Process::sys$getpid()
|
||||||
{
|
{
|
||||||
VERIFY_NO_PROCESS_BIG_LOCK(this)
|
VERIFY_NO_PROCESS_BIG_LOCK(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
return pid().value();
|
return pid().value();
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<FlatPtr> Process::sys$getppid()
|
ErrorOr<FlatPtr> Process::sys$getppid()
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
return m_protected_values.ppid.value();
|
return m_protected_values.ppid.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<FlatPtr> Process::sys$get_process_name(Userspace<char*> buffer, size_t buffer_size)
|
ErrorOr<FlatPtr> Process::sys$get_process_name(Userspace<char*> buffer, size_t buffer_size)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
if (m_name->length() + 1 > buffer_size)
|
if (m_name->length() + 1 > buffer_size)
|
||||||
return ENAMETOOLONG;
|
return ENAMETOOLONG;
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ ErrorOr<FlatPtr> Process::sys$get_process_name(Userspace<char*> buffer, size_t b
|
||||||
ErrorOr<FlatPtr> Process::sys$set_process_name(Userspace<const char*> user_name, size_t user_name_length)
|
ErrorOr<FlatPtr> Process::sys$set_process_name(Userspace<const char*> user_name, size_t user_name_length)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::proc);
|
TRY(require_promise(Pledge::proc));
|
||||||
if (user_name_length > 256)
|
if (user_name_length > 256)
|
||||||
return ENAMETOOLONG;
|
return ENAMETOOLONG;
|
||||||
auto name = TRY(try_copy_kstring_from_user(user_name, user_name_length));
|
auto name = TRY(try_copy_kstring_from_user(user_name, user_name_length));
|
||||||
|
|
|
@ -19,7 +19,7 @@ u64 g_profiling_event_mask;
|
||||||
ErrorOr<FlatPtr> Process::sys$profiling_enable(pid_t pid, u64 event_mask)
|
ErrorOr<FlatPtr> Process::sys$profiling_enable(pid_t pid, u64 event_mask)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_no_promises();
|
TRY(require_no_promises());
|
||||||
|
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
|
@ -69,7 +69,7 @@ ErrorOr<FlatPtr> Process::sys$profiling_enable(pid_t pid, u64 event_mask)
|
||||||
ErrorOr<FlatPtr> Process::sys$profiling_disable(pid_t pid)
|
ErrorOr<FlatPtr> Process::sys$profiling_disable(pid_t pid)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_no_promises();
|
TRY(require_no_promises());
|
||||||
|
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
|
@ -99,7 +99,7 @@ ErrorOr<FlatPtr> Process::sys$profiling_disable(pid_t pid)
|
||||||
ErrorOr<FlatPtr> Process::sys$profiling_free_buffer(pid_t pid)
|
ErrorOr<FlatPtr> Process::sys$profiling_free_buffer(pid_t pid)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_no_promises();
|
TRY(require_no_promises());
|
||||||
|
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
|
|
|
@ -159,7 +159,7 @@ static ErrorOr<FlatPtr> handle_ptrace(const Kernel::Syscall::SC_ptrace_params& p
|
||||||
ErrorOr<FlatPtr> Process::sys$ptrace(Userspace<const Syscall::SC_ptrace_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$ptrace(Userspace<const Syscall::SC_ptrace_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::ptrace);
|
TRY(require_promise(Pledge::ptrace));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
|
|
||||||
return handle_ptrace(params, *this);
|
return handle_ptrace(params, *this);
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$purge(int mode)
|
ErrorOr<FlatPtr> Process::sys$purge(int mode)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_no_promises();
|
TRY(require_no_promises());
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return EPERM;
|
return EPERM;
|
||||||
size_t purged_page_count = 0;
|
size_t purged_page_count = 0;
|
||||||
|
|
|
@ -40,7 +40,7 @@ static ErrorOr<void> check_blocked_read(OpenFileDescription* description)
|
||||||
ErrorOr<FlatPtr> Process::sys$readv(int fd, Userspace<const struct iovec*> iov, int iov_count)
|
ErrorOr<FlatPtr> Process::sys$readv(int fd, Userspace<const struct iovec*> iov, int iov_count)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
if (iov_count < 0)
|
if (iov_count < 0)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ ErrorOr<FlatPtr> Process::sys$readv(int fd, Userspace<const struct iovec*> iov,
|
||||||
ErrorOr<FlatPtr> Process::sys$read(int fd, Userspace<u8*> buffer, size_t size)
|
ErrorOr<FlatPtr> Process::sys$read(int fd, Userspace<u8*> buffer, size_t size)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (size > NumericLimits<ssize_t>::max())
|
if (size > NumericLimits<ssize_t>::max())
|
||||||
|
@ -91,7 +91,7 @@ ErrorOr<FlatPtr> Process::sys$read(int fd, Userspace<u8*> buffer, size_t size)
|
||||||
ErrorOr<FlatPtr> Process::sys$pread(int fd, Userspace<u8*> buffer, size_t size, Userspace<off_t const*> userspace_offset)
|
ErrorOr<FlatPtr> Process::sys$pread(int fd, Userspace<u8*> buffer, size_t size, Userspace<off_t const*> userspace_offset)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (size > NumericLimits<ssize_t>::max())
|
if (size > NumericLimits<ssize_t>::max())
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$readlink(Userspace<const Syscall::SC_readlink_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$readlink(Userspace<const Syscall::SC_readlink_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::rpath);
|
TRY(require_promise(Pledge::rpath));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
|
|
||||||
auto path = TRY(get_syscall_path_argument(params.path));
|
auto path = TRY(get_syscall_path_argument(params.path));
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$realpath(Userspace<const Syscall::SC_realpath_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$realpath(Userspace<const Syscall::SC_realpath_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::rpath);
|
TRY(require_promise(Pledge::rpath));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
|
|
||||||
auto path = TRY(get_syscall_path_argument(params.path));
|
auto path = TRY(get_syscall_path_argument(params.path));
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$rename(Userspace<const Syscall::SC_rename_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$rename(Userspace<const Syscall::SC_rename_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::cpath);
|
TRY(require_promise(Pledge::cpath));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
auto old_path = TRY(get_syscall_path_argument(params.old_path));
|
auto old_path = TRY(get_syscall_path_argument(params.old_path));
|
||||||
auto new_path = TRY(get_syscall_path_argument(params.new_path));
|
auto new_path = TRY(get_syscall_path_argument(params.new_path));
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$rmdir(Userspace<const char*> user_path, size_t path_length)
|
ErrorOr<FlatPtr> Process::sys$rmdir(Userspace<const char*> user_path, size_t path_length)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::cpath);
|
TRY(require_promise(Pledge::cpath));
|
||||||
auto path = TRY(get_syscall_path_argument(user_path, path_length));
|
auto path = TRY(get_syscall_path_argument(user_path, path_length));
|
||||||
TRY(VirtualFileSystem::the().rmdir(path->view(), current_directory()));
|
TRY(VirtualFileSystem::the().rmdir(path->view(), current_directory()));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$yield()
|
ErrorOr<FlatPtr> Process::sys$yield()
|
||||||
{
|
{
|
||||||
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
Thread::current()->yield_without_releasing_big_lock();
|
Thread::current()->yield_without_releasing_big_lock();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ ErrorOr<FlatPtr> Process::sys$yield()
|
||||||
ErrorOr<FlatPtr> Process::sys$sched_setparam(int pid, Userspace<const struct sched_param*> user_param)
|
ErrorOr<FlatPtr> Process::sys$sched_setparam(int pid, Userspace<const struct sched_param*> user_param)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::proc);
|
TRY(require_promise(Pledge::proc));
|
||||||
auto param = TRY(copy_typed_from_user(user_param));
|
auto param = TRY(copy_typed_from_user(user_param));
|
||||||
|
|
||||||
if (param.sched_priority < THREAD_PRIORITY_MIN || param.sched_priority > THREAD_PRIORITY_MAX)
|
if (param.sched_priority < THREAD_PRIORITY_MIN || param.sched_priority > THREAD_PRIORITY_MAX)
|
||||||
|
@ -43,7 +43,7 @@ ErrorOr<FlatPtr> Process::sys$sched_setparam(int pid, Userspace<const struct sch
|
||||||
ErrorOr<FlatPtr> Process::sys$sched_getparam(pid_t pid, Userspace<struct sched_param*> user_param)
|
ErrorOr<FlatPtr> Process::sys$sched_getparam(pid_t pid, Userspace<struct sched_param*> user_param)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::proc);
|
TRY(require_promise(Pledge::proc));
|
||||||
int priority;
|
int priority;
|
||||||
{
|
{
|
||||||
auto* peer = Thread::current();
|
auto* peer = Thread::current();
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$sendfd(int sockfd, int fd)
|
ErrorOr<FlatPtr> Process::sys$sendfd(int sockfd, int fd)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::sendfd);
|
TRY(require_promise(Pledge::sendfd));
|
||||||
auto socket_description = TRY(fds().open_file_description(sockfd));
|
auto socket_description = TRY(fds().open_file_description(sockfd));
|
||||||
if (!socket_description->is_socket())
|
if (!socket_description->is_socket())
|
||||||
return ENOTSOCK;
|
return ENOTSOCK;
|
||||||
|
@ -32,7 +32,7 @@ ErrorOr<FlatPtr> Process::sys$sendfd(int sockfd, int fd)
|
||||||
ErrorOr<FlatPtr> Process::sys$recvfd(int sockfd, int options)
|
ErrorOr<FlatPtr> Process::sys$recvfd(int sockfd, int options)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::recvfd);
|
TRY(require_promise(Pledge::recvfd));
|
||||||
auto socket_description = TRY(fds().open_file_description(sockfd));
|
auto socket_description = TRY(fds().open_file_description(sockfd));
|
||||||
if (!socket_description->is_socket())
|
if (!socket_description->is_socket())
|
||||||
return ENOTSOCK;
|
return ENOTSOCK;
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$getsid(pid_t pid)
|
ErrorOr<FlatPtr> Process::sys$getsid(pid_t pid)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::proc);
|
TRY(require_promise(Pledge::proc));
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
return sid().value();
|
return sid().value();
|
||||||
auto process = Process::from_pid(pid);
|
auto process = Process::from_pid(pid);
|
||||||
|
@ -27,7 +27,7 @@ ErrorOr<FlatPtr> Process::sys$getsid(pid_t pid)
|
||||||
ErrorOr<FlatPtr> Process::sys$setsid()
|
ErrorOr<FlatPtr> Process::sys$setsid()
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::proc);
|
TRY(require_promise(Pledge::proc));
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
bool found_process_with_same_pgid_as_my_pid = false;
|
bool found_process_with_same_pgid_as_my_pid = false;
|
||||||
Process::for_each_in_pgrp(pid().value(), [&](auto&) {
|
Process::for_each_in_pgrp(pid().value(), [&](auto&) {
|
||||||
|
@ -48,7 +48,7 @@ ErrorOr<FlatPtr> Process::sys$setsid()
|
||||||
ErrorOr<FlatPtr> Process::sys$getpgid(pid_t pid)
|
ErrorOr<FlatPtr> Process::sys$getpgid(pid_t pid)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::proc);
|
TRY(require_promise(Pledge::proc));
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
return pgid().value();
|
return pgid().value();
|
||||||
auto process = Process::from_pid(pid);
|
auto process = Process::from_pid(pid);
|
||||||
|
@ -60,7 +60,7 @@ ErrorOr<FlatPtr> Process::sys$getpgid(pid_t pid)
|
||||||
ErrorOr<FlatPtr> Process::sys$getpgrp()
|
ErrorOr<FlatPtr> Process::sys$getpgrp()
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
return pgid().value();
|
return pgid().value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ SessionID Process::get_sid_from_pgid(ProcessGroupID pgid)
|
||||||
ErrorOr<FlatPtr> Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
|
ErrorOr<FlatPtr> Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::proc);
|
TRY(require_promise(Pledge::proc));
|
||||||
ProcessID pid = specified_pid ? ProcessID(specified_pid) : this->pid();
|
ProcessID pid = specified_pid ? ProcessID(specified_pid) : this->pid();
|
||||||
if (specified_pgid < 0) {
|
if (specified_pgid < 0) {
|
||||||
// The value of the pgid argument is less than 0, or is not a value supported by the implementation.
|
// The value of the pgid argument is less than 0, or is not a value supported by the implementation.
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$seteuid(UserID new_euid)
|
ErrorOr<FlatPtr> Process::sys$seteuid(UserID new_euid)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::id);
|
TRY(require_promise(Pledge::id));
|
||||||
|
|
||||||
if (new_euid == (uid_t)-1)
|
if (new_euid == (uid_t)-1)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
@ -31,7 +31,7 @@ ErrorOr<FlatPtr> Process::sys$seteuid(UserID new_euid)
|
||||||
ErrorOr<FlatPtr> Process::sys$setegid(GroupID new_egid)
|
ErrorOr<FlatPtr> Process::sys$setegid(GroupID new_egid)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::id);
|
TRY(require_promise(Pledge::id));
|
||||||
|
|
||||||
if (new_egid == (uid_t)-1)
|
if (new_egid == (uid_t)-1)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
@ -50,7 +50,7 @@ ErrorOr<FlatPtr> Process::sys$setegid(GroupID new_egid)
|
||||||
ErrorOr<FlatPtr> Process::sys$setuid(UserID new_uid)
|
ErrorOr<FlatPtr> Process::sys$setuid(UserID new_uid)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::id);
|
TRY(require_promise(Pledge::id));
|
||||||
|
|
||||||
if (new_uid == (uid_t)-1)
|
if (new_uid == (uid_t)-1)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
@ -71,7 +71,7 @@ ErrorOr<FlatPtr> Process::sys$setuid(UserID new_uid)
|
||||||
ErrorOr<FlatPtr> Process::sys$setgid(GroupID new_gid)
|
ErrorOr<FlatPtr> Process::sys$setgid(GroupID new_gid)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::id);
|
TRY(require_promise(Pledge::id));
|
||||||
|
|
||||||
if (new_gid == (uid_t)-1)
|
if (new_gid == (uid_t)-1)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
@ -92,7 +92,7 @@ ErrorOr<FlatPtr> Process::sys$setgid(GroupID new_gid)
|
||||||
ErrorOr<FlatPtr> Process::sys$setreuid(UserID new_ruid, UserID new_euid)
|
ErrorOr<FlatPtr> Process::sys$setreuid(UserID new_ruid, UserID new_euid)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::id);
|
TRY(require_promise(Pledge::id));
|
||||||
|
|
||||||
if (new_ruid == (uid_t)-1)
|
if (new_ruid == (uid_t)-1)
|
||||||
new_ruid = uid();
|
new_ruid = uid();
|
||||||
|
@ -118,7 +118,7 @@ ErrorOr<FlatPtr> Process::sys$setreuid(UserID new_ruid, UserID new_euid)
|
||||||
ErrorOr<FlatPtr> Process::sys$setresuid(UserID new_ruid, UserID new_euid, UserID new_suid)
|
ErrorOr<FlatPtr> Process::sys$setresuid(UserID new_ruid, UserID new_euid, UserID new_suid)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::id);
|
TRY(require_promise(Pledge::id));
|
||||||
|
|
||||||
if (new_ruid == (uid_t)-1)
|
if (new_ruid == (uid_t)-1)
|
||||||
new_ruid = uid();
|
new_ruid = uid();
|
||||||
|
@ -144,7 +144,7 @@ ErrorOr<FlatPtr> Process::sys$setresuid(UserID new_ruid, UserID new_euid, UserID
|
||||||
ErrorOr<FlatPtr> Process::sys$setresgid(GroupID new_rgid, GroupID new_egid, GroupID new_sgid)
|
ErrorOr<FlatPtr> Process::sys$setresgid(GroupID new_rgid, GroupID new_egid, GroupID new_sgid)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::id);
|
TRY(require_promise(Pledge::id));
|
||||||
|
|
||||||
if (new_rgid == (gid_t)-1)
|
if (new_rgid == (gid_t)-1)
|
||||||
new_rgid = gid();
|
new_rgid = gid();
|
||||||
|
@ -170,7 +170,7 @@ ErrorOr<FlatPtr> Process::sys$setresgid(GroupID new_rgid, GroupID new_egid, Grou
|
||||||
ErrorOr<FlatPtr> Process::sys$setgroups(size_t count, Userspace<const gid_t*> user_gids)
|
ErrorOr<FlatPtr> Process::sys$setgroups(size_t count, Userspace<const gid_t*> user_gids)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::id);
|
TRY(require_promise(Pledge::id));
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return EPERM;
|
return EPERM;
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$sigprocmask(int how, Userspace<const sigset_t*> set, Userspace<sigset_t*> old_set)
|
ErrorOr<FlatPtr> Process::sys$sigprocmask(int how, Userspace<const sigset_t*> set, Userspace<sigset_t*> old_set)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::sigaction);
|
TRY(require_promise(Pledge::sigaction));
|
||||||
auto* current_thread = Thread::current();
|
auto* current_thread = Thread::current();
|
||||||
u32 previous_signal_mask;
|
u32 previous_signal_mask;
|
||||||
if (set) {
|
if (set) {
|
||||||
|
@ -44,7 +44,7 @@ ErrorOr<FlatPtr> Process::sys$sigprocmask(int how, Userspace<const sigset_t*> se
|
||||||
ErrorOr<FlatPtr> Process::sys$sigpending(Userspace<sigset_t*> set)
|
ErrorOr<FlatPtr> Process::sys$sigpending(Userspace<sigset_t*> set)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
auto pending_signals = Thread::current()->pending_signals();
|
auto pending_signals = Thread::current()->pending_signals();
|
||||||
TRY(copy_to_user(set, &pending_signals));
|
TRY(copy_to_user(set, &pending_signals));
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -53,7 +53,7 @@ ErrorOr<FlatPtr> Process::sys$sigpending(Userspace<sigset_t*> set)
|
||||||
ErrorOr<FlatPtr> Process::sys$sigaction(int signum, Userspace<const sigaction*> user_act, Userspace<sigaction*> user_old_act)
|
ErrorOr<FlatPtr> Process::sys$sigaction(int signum, Userspace<const sigaction*> user_act, Userspace<sigaction*> user_old_act)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::sigaction);
|
TRY(require_promise(Pledge::sigaction));
|
||||||
if (signum < 1 || signum >= 32 || signum == SIGKILL || signum == SIGSTOP)
|
if (signum < 1 || signum >= 32 || signum == SIGKILL || signum == SIGSTOP)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ ErrorOr<FlatPtr> Process::sys$sigaction(int signum, Userspace<const sigaction*>
|
||||||
ErrorOr<FlatPtr> Process::sys$sigreturn([[maybe_unused]] RegisterState& registers)
|
ErrorOr<FlatPtr> Process::sys$sigreturn([[maybe_unused]] RegisterState& registers)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
SmapDisabler disabler;
|
SmapDisabler disabler;
|
||||||
|
|
||||||
#if ARCH(I386)
|
#if ARCH(I386)
|
||||||
|
@ -258,7 +258,7 @@ ErrorOr<void> Process::remap_range_as_stack(FlatPtr address, size_t size)
|
||||||
ErrorOr<FlatPtr> Process::sys$sigaltstack(Userspace<const stack_t*> user_ss, Userspace<stack_t*> user_old_ss)
|
ErrorOr<FlatPtr> Process::sys$sigaltstack(Userspace<const stack_t*> user_ss, Userspace<stack_t*> user_old_ss)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::sigaction);
|
TRY(require_promise(Pledge::sigaction));
|
||||||
|
|
||||||
if (user_old_ss) {
|
if (user_old_ss) {
|
||||||
stack_t old_ss_value {};
|
stack_t old_ss_value {};
|
||||||
|
@ -307,7 +307,7 @@ ErrorOr<FlatPtr> Process::sys$sigaltstack(Userspace<const stack_t*> user_ss, Use
|
||||||
ErrorOr<FlatPtr> Process::sys$sigtimedwait(Userspace<const sigset_t*> set, Userspace<siginfo_t*> info, Userspace<const timespec*> timeout)
|
ErrorOr<FlatPtr> Process::sys$sigtimedwait(Userspace<const sigset_t*> set, Userspace<siginfo_t*> info, Userspace<const timespec*> timeout)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::sigaction);
|
TRY(require_promise(Pledge::sigaction));
|
||||||
|
|
||||||
sigset_t set_value;
|
sigset_t set_value;
|
||||||
TRY(copy_from_user(&set_value, set));
|
TRY(copy_from_user(&set_value, set));
|
||||||
|
|
|
@ -14,9 +14,9 @@ namespace Kernel {
|
||||||
#define REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(domain) \
|
#define REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(domain) \
|
||||||
do { \
|
do { \
|
||||||
if (domain == AF_INET) \
|
if (domain == AF_INET) \
|
||||||
require_promise(Pledge::inet); \
|
TRY(require_promise(Pledge::inet)); \
|
||||||
else if (domain == AF_LOCAL) \
|
else if (domain == AF_LOCAL) \
|
||||||
require_promise(Pledge::unix); \
|
TRY(require_promise(Pledge::unix)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
void Process::setup_socket_fd(int fd, NonnullRefPtr<OpenFileDescription> description, int type)
|
void Process::setup_socket_fd(int fd, NonnullRefPtr<OpenFileDescription> description, int type)
|
||||||
|
@ -76,7 +76,7 @@ ErrorOr<FlatPtr> Process::sys$listen(int sockfd, int backlog)
|
||||||
ErrorOr<FlatPtr> Process::sys$accept4(Userspace<const Syscall::SC_accept4_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$accept4(Userspace<const Syscall::SC_accept4_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::accept);
|
TRY(require_promise(Pledge::accept));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
|
|
||||||
int accepting_socket_fd = params.sockfd;
|
int accepting_socket_fd = params.sockfd;
|
||||||
|
@ -146,7 +146,7 @@ ErrorOr<FlatPtr> Process::sys$connect(int sockfd, Userspace<const sockaddr*> use
|
||||||
ErrorOr<FlatPtr> Process::sys$shutdown(int sockfd, int how)
|
ErrorOr<FlatPtr> Process::sys$shutdown(int sockfd, int how)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
if (how & ~SHUT_RDWR)
|
if (how & ~SHUT_RDWR)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
auto description = TRY(fds().open_file_description(sockfd));
|
auto description = TRY(fds().open_file_description(sockfd));
|
||||||
|
@ -161,7 +161,7 @@ ErrorOr<FlatPtr> Process::sys$shutdown(int sockfd, int how)
|
||||||
ErrorOr<FlatPtr> Process::sys$sendmsg(int sockfd, Userspace<const struct msghdr*> user_msg, int flags)
|
ErrorOr<FlatPtr> Process::sys$sendmsg(int sockfd, Userspace<const struct msghdr*> user_msg, int flags)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
auto msg = TRY(copy_typed_from_user(user_msg));
|
auto msg = TRY(copy_typed_from_user(user_msg));
|
||||||
|
|
||||||
if (msg.msg_iovlen != 1)
|
if (msg.msg_iovlen != 1)
|
||||||
|
@ -189,7 +189,7 @@ ErrorOr<FlatPtr> Process::sys$sendmsg(int sockfd, Userspace<const struct msghdr*
|
||||||
ErrorOr<FlatPtr> Process::sys$recvmsg(int sockfd, Userspace<struct msghdr*> user_msg, int flags)
|
ErrorOr<FlatPtr> Process::sys$recvmsg(int sockfd, Userspace<struct msghdr*> user_msg, int flags)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
|
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
TRY(copy_from_user(&msg, user_msg));
|
TRY(copy_from_user(&msg, user_msg));
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$fstat(int fd, Userspace<stat*> user_statbuf)
|
ErrorOr<FlatPtr> Process::sys$fstat(int fd, Userspace<stat*> user_statbuf)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
auto description = TRY(fds().open_file_description(fd));
|
auto description = TRY(fds().open_file_description(fd));
|
||||||
auto buffer = TRY(description->stat());
|
auto buffer = TRY(description->stat());
|
||||||
TRY(copy_to_user(user_statbuf, &buffer));
|
TRY(copy_to_user(user_statbuf, &buffer));
|
||||||
|
@ -24,7 +24,7 @@ ErrorOr<FlatPtr> Process::sys$fstat(int fd, Userspace<stat*> user_statbuf)
|
||||||
ErrorOr<FlatPtr> Process::sys$stat(Userspace<const Syscall::SC_stat_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$stat(Userspace<const Syscall::SC_stat_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::rpath);
|
TRY(require_promise(Pledge::rpath));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
|
|
||||||
auto path = TRY(get_syscall_path_argument(params.path));
|
auto path = TRY(get_syscall_path_argument(params.path));
|
||||||
|
|
|
@ -40,7 +40,7 @@ ErrorOr<FlatPtr> Process::do_statvfs(FileSystem const& fs, Custody const* custod
|
||||||
ErrorOr<FlatPtr> Process::sys$statvfs(Userspace<const Syscall::SC_statvfs_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$statvfs(Userspace<const Syscall::SC_statvfs_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::rpath);
|
TRY(require_promise(Pledge::rpath));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
|
|
||||||
auto path = TRY(get_syscall_path_argument(params.path));
|
auto path = TRY(get_syscall_path_argument(params.path));
|
||||||
|
@ -55,7 +55,7 @@ ErrorOr<FlatPtr> Process::sys$statvfs(Userspace<const Syscall::SC_statvfs_params
|
||||||
ErrorOr<FlatPtr> Process::sys$fstatvfs(int fd, statvfs* buf)
|
ErrorOr<FlatPtr> Process::sys$fstatvfs(int fd, statvfs* buf)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
|
|
||||||
auto description = TRY(fds().open_file_description(fd));
|
auto description = TRY(fds().open_file_description(fd));
|
||||||
auto const* inode = description->inode();
|
auto const* inode = description->inode();
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$sync()
|
ErrorOr<FlatPtr> Process::sys$sync()
|
||||||
{
|
{
|
||||||
VERIFY_NO_PROCESS_BIG_LOCK(this)
|
VERIFY_NO_PROCESS_BIG_LOCK(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
VirtualFileSystem::sync();
|
VirtualFileSystem::sync();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$create_thread(void* (*entry)(void*), Userspace<const Syscall::SC_create_thread_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$create_thread(void* (*entry)(void*), Userspace<const Syscall::SC_create_thread_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::thread);
|
TRY(require_promise(Pledge::thread));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
|
|
||||||
unsigned detach_state = params.detach_state;
|
unsigned detach_state = params.detach_state;
|
||||||
|
@ -74,7 +74,12 @@ ErrorOr<FlatPtr> Process::sys$create_thread(void* (*entry)(void*), Userspace<con
|
||||||
void Process::sys$exit_thread(Userspace<void*> exit_value, Userspace<void*> stack_location, size_t stack_size)
|
void Process::sys$exit_thread(Userspace<void*> exit_value, Userspace<void*> stack_location, size_t stack_size)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::thread);
|
|
||||||
|
auto result = require_promise(Pledge::thread);
|
||||||
|
if (result.is_error()) {
|
||||||
|
// Crash now, as we will never reach back to the syscall handler.
|
||||||
|
crash(SIGABRT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (this->thread_count() == 1) {
|
if (this->thread_count() == 1) {
|
||||||
// If this is the last thread, instead kill the process.
|
// If this is the last thread, instead kill the process.
|
||||||
|
@ -98,7 +103,7 @@ void Process::sys$exit_thread(Userspace<void*> exit_value, Userspace<void*> stac
|
||||||
ErrorOr<FlatPtr> Process::sys$detach_thread(pid_t tid)
|
ErrorOr<FlatPtr> Process::sys$detach_thread(pid_t tid)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::thread);
|
TRY(require_promise(Pledge::thread));
|
||||||
auto thread = Thread::from_tid(tid);
|
auto thread = Thread::from_tid(tid);
|
||||||
if (!thread || thread->pid() != pid())
|
if (!thread || thread->pid() != pid())
|
||||||
return ESRCH;
|
return ESRCH;
|
||||||
|
@ -113,7 +118,7 @@ ErrorOr<FlatPtr> Process::sys$detach_thread(pid_t tid)
|
||||||
ErrorOr<FlatPtr> Process::sys$join_thread(pid_t tid, Userspace<void**> exit_value)
|
ErrorOr<FlatPtr> Process::sys$join_thread(pid_t tid, Userspace<void**> exit_value)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::thread);
|
TRY(require_promise(Pledge::thread));
|
||||||
|
|
||||||
auto thread = Thread::from_tid(tid);
|
auto thread = Thread::from_tid(tid);
|
||||||
if (!thread || thread->pid() != pid())
|
if (!thread || thread->pid() != pid())
|
||||||
|
@ -148,7 +153,7 @@ ErrorOr<FlatPtr> Process::sys$join_thread(pid_t tid, Userspace<void**> exit_valu
|
||||||
ErrorOr<FlatPtr> Process::sys$kill_thread(pid_t tid, int signal)
|
ErrorOr<FlatPtr> Process::sys$kill_thread(pid_t tid, int signal)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::thread);
|
TRY(require_promise(Pledge::thread));
|
||||||
|
|
||||||
if (signal < 0 || signal >= 32)
|
if (signal < 0 || signal >= 32)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
@ -166,7 +171,7 @@ ErrorOr<FlatPtr> Process::sys$kill_thread(pid_t tid, int signal)
|
||||||
ErrorOr<FlatPtr> Process::sys$set_thread_name(pid_t tid, Userspace<const char*> user_name, size_t user_name_length)
|
ErrorOr<FlatPtr> Process::sys$set_thread_name(pid_t tid, Userspace<const char*> user_name, size_t user_name_length)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
|
|
||||||
auto name = TRY(try_copy_kstring_from_user(user_name, user_name_length));
|
auto name = TRY(try_copy_kstring_from_user(user_name, user_name_length));
|
||||||
|
|
||||||
|
@ -185,7 +190,7 @@ ErrorOr<FlatPtr> Process::sys$set_thread_name(pid_t tid, Userspace<const char*>
|
||||||
ErrorOr<FlatPtr> Process::sys$get_thread_name(pid_t tid, Userspace<char*> buffer, size_t buffer_size)
|
ErrorOr<FlatPtr> Process::sys$get_thread_name(pid_t tid, Userspace<char*> buffer, size_t buffer_size)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::thread);
|
TRY(require_promise(Pledge::thread));
|
||||||
if (buffer_size == 0)
|
if (buffer_size == 0)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
|
@ -212,7 +217,7 @@ ErrorOr<FlatPtr> Process::sys$get_thread_name(pid_t tid, Userspace<char*> buffer
|
||||||
ErrorOr<FlatPtr> Process::sys$gettid()
|
ErrorOr<FlatPtr> Process::sys$gettid()
|
||||||
{
|
{
|
||||||
VERIFY_NO_PROCESS_BIG_LOCK(this)
|
VERIFY_NO_PROCESS_BIG_LOCK(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
return Thread::current()->tid().value();
|
return Thread::current()->tid().value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$times(Userspace<tms*> user_times)
|
ErrorOr<FlatPtr> Process::sys$times(Userspace<tms*> user_times)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
tms times = {};
|
tms times = {};
|
||||||
times.tms_utime = m_ticks_in_user;
|
times.tms_utime = m_ticks_in_user;
|
||||||
times.tms_stime = m_ticks_in_kernel;
|
times.tms_stime = m_ticks_in_kernel;
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$ttyname(int fd, Userspace<char*> buffer, size_t size)
|
ErrorOr<FlatPtr> Process::sys$ttyname(int fd, Userspace<char*> buffer, size_t size)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::tty);
|
TRY(require_promise(Pledge::tty));
|
||||||
auto description = TRY(fds().open_file_description(fd));
|
auto description = TRY(fds().open_file_description(fd));
|
||||||
if (!description->is_tty())
|
if (!description->is_tty())
|
||||||
return ENOTTY;
|
return ENOTTY;
|
||||||
|
@ -28,7 +28,7 @@ ErrorOr<FlatPtr> Process::sys$ttyname(int fd, Userspace<char*> buffer, size_t si
|
||||||
ErrorOr<FlatPtr> Process::sys$ptsname(int fd, Userspace<char*> buffer, size_t size)
|
ErrorOr<FlatPtr> Process::sys$ptsname(int fd, Userspace<char*> buffer, size_t size)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::tty);
|
TRY(require_promise(Pledge::tty));
|
||||||
auto description = TRY(fds().open_file_description(fd));
|
auto description = TRY(fds().open_file_description(fd));
|
||||||
auto* master_pty = description->master_pty();
|
auto* master_pty = description->master_pty();
|
||||||
if (!master_pty)
|
if (!master_pty)
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$umask(mode_t mask)
|
ErrorOr<FlatPtr> Process::sys$umask(mode_t mask)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
auto old_mask = m_protected_values.umask;
|
auto old_mask = m_protected_values.umask;
|
||||||
ProtectedDataMutationScope scope { *this };
|
ProtectedDataMutationScope scope { *this };
|
||||||
m_protected_values.umask = mask & 0777;
|
m_protected_values.umask = mask & 0777;
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$uname(Userspace<utsname*> user_buf)
|
ErrorOr<FlatPtr> Process::sys$uname(Userspace<utsname*> user_buf)
|
||||||
{
|
{
|
||||||
VERIFY_NO_PROCESS_BIG_LOCK(this)
|
VERIFY_NO_PROCESS_BIG_LOCK(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
|
|
||||||
utsname buf {};
|
utsname buf {};
|
||||||
memcpy(buf.sysname, "SerenityOS", 11);
|
memcpy(buf.sysname, "SerenityOS", 11);
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$unlink(Userspace<const char*> user_path, size_t path_length)
|
ErrorOr<FlatPtr> Process::sys$unlink(Userspace<const char*> user_path, size_t path_length)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::cpath);
|
TRY(require_promise(Pledge::cpath));
|
||||||
auto path = TRY(get_syscall_path_argument(user_path, path_length));
|
auto path = TRY(get_syscall_path_argument(user_path, path_length));
|
||||||
TRY(VirtualFileSystem::the().unlink(path->view(), current_directory()));
|
TRY(VirtualFileSystem::the().unlink(path->view(), current_directory()));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$utime(Userspace<const char*> user_path, size_t path_length, Userspace<const struct utimbuf*> user_buf)
|
ErrorOr<FlatPtr> Process::sys$utime(Userspace<const char*> user_path, size_t path_length, Userspace<const struct utimbuf*> user_buf)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::fattr);
|
TRY(require_promise(Pledge::fattr));
|
||||||
auto path = TRY(get_syscall_path_argument(user_path, path_length));
|
auto path = TRY(get_syscall_path_argument(user_path, path_length));
|
||||||
utimbuf buf;
|
utimbuf buf;
|
||||||
if (user_buf) {
|
if (user_buf) {
|
||||||
|
|
|
@ -22,7 +22,7 @@ ErrorOr<siginfo_t> Process::do_waitid(Variant<Empty, NonnullRefPtr<Process>, Non
|
||||||
ErrorOr<FlatPtr> Process::sys$waitid(Userspace<const Syscall::SC_waitid_params*> user_params)
|
ErrorOr<FlatPtr> Process::sys$waitid(Userspace<const Syscall::SC_waitid_params*> user_params)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::proc);
|
TRY(require_promise(Pledge::proc));
|
||||||
auto params = TRY(copy_typed_from_user(user_params));
|
auto params = TRY(copy_typed_from_user(user_params));
|
||||||
|
|
||||||
Variant<Empty, NonnullRefPtr<Process>, NonnullRefPtr<ProcessGroup>> waitee;
|
Variant<Empty, NonnullRefPtr<Process>, NonnullRefPtr<ProcessGroup>> waitee;
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Kernel {
|
||||||
ErrorOr<FlatPtr> Process::sys$writev(int fd, Userspace<const struct iovec*> iov, int iov_count)
|
ErrorOr<FlatPtr> Process::sys$writev(int fd, Userspace<const struct iovec*> iov, int iov_count)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
if (iov_count < 0)
|
if (iov_count < 0)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ ErrorOr<FlatPtr> Process::do_write(OpenFileDescription& description, const UserO
|
||||||
ErrorOr<FlatPtr> Process::sys$write(int fd, Userspace<const u8*> data, size_t size)
|
ErrorOr<FlatPtr> Process::sys$write(int fd, Userspace<const u8*> data, size_t size)
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
require_promise(Pledge::stdio);
|
TRY(require_promise(Pledge::stdio));
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (size > NumericLimits<ssize_t>::max())
|
if (size > NumericLimits<ssize_t>::max())
|
||||||
|
|
|
@ -122,7 +122,7 @@ ErrorOr<void> MasterPTY::close()
|
||||||
|
|
||||||
ErrorOr<void> MasterPTY::ioctl(OpenFileDescription& description, unsigned request, Userspace<void*> arg)
|
ErrorOr<void> MasterPTY::ioctl(OpenFileDescription& description, unsigned request, Userspace<void*> arg)
|
||||||
{
|
{
|
||||||
Process::current().require_promise(Pledge::tty);
|
TRY(Process::current().require_promise(Pledge::tty));
|
||||||
if (!m_slave)
|
if (!m_slave)
|
||||||
return EIO;
|
return EIO;
|
||||||
if (request == TIOCSWINSZ || request == TIOCGPGRP)
|
if (request == TIOCSWINSZ || request == TIOCGPGRP)
|
||||||
|
|
|
@ -475,7 +475,7 @@ ErrorOr<void> TTY::set_termios(const termios& t)
|
||||||
ErrorOr<void> TTY::ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg)
|
ErrorOr<void> TTY::ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg)
|
||||||
{
|
{
|
||||||
auto& current_process = Process::current();
|
auto& current_process = Process::current();
|
||||||
current_process.require_promise(Pledge::tty);
|
TRY(current_process.require_promise(Pledge::tty));
|
||||||
#if 0
|
#if 0
|
||||||
// FIXME: When should we block things?
|
// FIXME: When should we block things?
|
||||||
// How do we make this work together with MasterPTY forwarding to us?
|
// How do we make this work together with MasterPTY forwarding to us?
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue