mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 19:07:35 +00:00
ping: Use pledge()
This commit is contained in:
parent
41c504a33b
commit
409a4f7756
4 changed files with 295 additions and 1 deletions
|
@ -53,6 +53,26 @@
|
||||||
//#define SIGNAL_DEBUG
|
//#define SIGNAL_DEBUG
|
||||||
//#define SHARED_BUFFER_DEBUG
|
//#define SHARED_BUFFER_DEBUG
|
||||||
|
|
||||||
|
#define REQUIRE_NO_PROMISES \
|
||||||
|
do { \
|
||||||
|
if (has_promises()) { \
|
||||||
|
dbg() << *current << " has made a promise"; \
|
||||||
|
cli(); \
|
||||||
|
crash(SIGABRT, 0); \
|
||||||
|
ASSERT_NOT_REACHED(); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define REQUIRE_PROMISE(promise) \
|
||||||
|
do { \
|
||||||
|
if (has_promises() && !has_promised(Pledge::promise)) { \
|
||||||
|
dbg() << *current << " has not pledged " << #promise; \
|
||||||
|
cli(); \
|
||||||
|
crash(SIGABRT, 0); \
|
||||||
|
ASSERT_NOT_REACHED(); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
static void create_signal_trampolines();
|
static void create_signal_trampolines();
|
||||||
static void create_kernel_info_page();
|
static void create_kernel_info_page();
|
||||||
|
|
||||||
|
@ -212,6 +232,8 @@ Region* Process::region_containing(const Range& range)
|
||||||
|
|
||||||
int Process::sys$set_mmap_name(const Syscall::SC_set_mmap_name_params* user_params)
|
int Process::sys$set_mmap_name(const Syscall::SC_set_mmap_name_params* user_params)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
|
|
||||||
if (!validate_read_typed(user_params))
|
if (!validate_read_typed(user_params))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
@ -281,6 +303,8 @@ Vector<Region*, 2> Process::split_region_around_range(const Region& source_regio
|
||||||
|
|
||||||
void* Process::sys$mmap(const Syscall::SC_mmap_params* user_params)
|
void* Process::sys$mmap(const Syscall::SC_mmap_params* user_params)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
|
|
||||||
if (!validate_read_typed(user_params))
|
if (!validate_read_typed(user_params))
|
||||||
return (void*)-EFAULT;
|
return (void*)-EFAULT;
|
||||||
|
|
||||||
|
@ -383,6 +407,7 @@ void* Process::sys$mmap(const Syscall::SC_mmap_params* user_params)
|
||||||
|
|
||||||
int Process::sys$munmap(void* addr, size_t size)
|
int Process::sys$munmap(void* addr, size_t size)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
Range range_to_unmap { VirtualAddress((u32)addr), size };
|
Range range_to_unmap { VirtualAddress((u32)addr), size };
|
||||||
if (auto* whole_region = region_from_range(range_to_unmap)) {
|
if (auto* whole_region = region_from_range(range_to_unmap)) {
|
||||||
if (!whole_region->is_mmap())
|
if (!whole_region->is_mmap())
|
||||||
|
@ -419,6 +444,7 @@ int Process::sys$munmap(void* addr, size_t size)
|
||||||
|
|
||||||
int Process::sys$mprotect(void* addr, size_t size, int prot)
|
int Process::sys$mprotect(void* addr, size_t size, int prot)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
Range range_to_mprotect = { VirtualAddress((u32)addr), size };
|
Range range_to_mprotect = { VirtualAddress((u32)addr), size };
|
||||||
|
|
||||||
if (auto* whole_region = region_from_range(range_to_mprotect)) {
|
if (auto* whole_region = region_from_range(range_to_mprotect)) {
|
||||||
|
@ -481,6 +507,7 @@ int Process::sys$mprotect(void* addr, size_t size, int prot)
|
||||||
|
|
||||||
int Process::sys$madvise(void* address, size_t size, int advice)
|
int Process::sys$madvise(void* address, size_t size, int advice)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
auto* region = region_from_range({ VirtualAddress((u32)address), size });
|
auto* region = region_from_range({ VirtualAddress((u32)address), size });
|
||||||
if (!region)
|
if (!region)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -517,6 +544,7 @@ int Process::sys$madvise(void* address, size_t size, int advice)
|
||||||
|
|
||||||
int Process::sys$purge(int mode)
|
int Process::sys$purge(int mode)
|
||||||
{
|
{
|
||||||
|
REQUIRE_NO_PROMISES;
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
int purged_page_count = 0;
|
int purged_page_count = 0;
|
||||||
|
@ -553,6 +581,7 @@ int Process::sys$purge(int mode)
|
||||||
|
|
||||||
int Process::sys$gethostname(char* buffer, ssize_t size)
|
int Process::sys$gethostname(char* buffer, ssize_t size)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!validate_write(buffer, size))
|
if (!validate_write(buffer, size))
|
||||||
|
@ -566,6 +595,7 @@ int Process::sys$gethostname(char* buffer, ssize_t size)
|
||||||
|
|
||||||
pid_t Process::sys$fork(RegisterDump& regs)
|
pid_t Process::sys$fork(RegisterDump& regs)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(proc);
|
||||||
Thread* child_first_thread = nullptr;
|
Thread* child_first_thread = nullptr;
|
||||||
auto* child = new Process(child_first_thread, m_name, m_uid, m_gid, m_pid, m_ring, m_cwd, m_executable, m_tty, this);
|
auto* child = new Process(child_first_thread, m_name, m_uid, m_gid, m_pid, m_ring, m_cwd, m_executable, m_tty, this);
|
||||||
child->m_root_directory = m_root_directory;
|
child->m_root_directory = m_root_directory;
|
||||||
|
@ -747,6 +777,8 @@ int Process::do_exec(String path, Vector<String> arguments, Vector<String> envir
|
||||||
m_elf_loader = move(loader);
|
m_elf_loader = move(loader);
|
||||||
m_executable = description->custody();
|
m_executable = description->custody();
|
||||||
|
|
||||||
|
m_promises = m_execpromises;
|
||||||
|
|
||||||
// Copy of the master TLS region that we will clone for new threads
|
// Copy of the master TLS region that we will clone for new threads
|
||||||
m_master_tls_region = master_tls_region;
|
m_master_tls_region = master_tls_region;
|
||||||
|
|
||||||
|
@ -914,6 +946,7 @@ int Process::exec(String path, Vector<String> arguments, Vector<String> environm
|
||||||
|
|
||||||
int Process::sys$execve(const Syscall::SC_execve_params* user_params)
|
int Process::sys$execve(const Syscall::SC_execve_params* user_params)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(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.
|
||||||
Syscall::SC_execve_params params;
|
Syscall::SC_execve_params params;
|
||||||
|
@ -1258,6 +1291,7 @@ int Process::fd_flags(int fd) const
|
||||||
|
|
||||||
ssize_t Process::sys$get_dir_entries(int fd, void* buffer, ssize_t size)
|
ssize_t Process::sys$get_dir_entries(int fd, void* buffer, ssize_t size)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!validate_write(buffer, size))
|
if (!validate_write(buffer, size))
|
||||||
|
@ -1270,6 +1304,7 @@ ssize_t Process::sys$get_dir_entries(int fd, void* buffer, ssize_t size)
|
||||||
|
|
||||||
int Process::sys$lseek(int fd, off_t offset, int whence)
|
int Process::sys$lseek(int fd, off_t offset, int whence)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
auto description = file_description(fd);
|
auto description = file_description(fd);
|
||||||
if (!description)
|
if (!description)
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
|
@ -1278,6 +1313,7 @@ int Process::sys$lseek(int fd, off_t offset, int whence)
|
||||||
|
|
||||||
int Process::sys$ttyname_r(int fd, char* buffer, ssize_t size)
|
int Process::sys$ttyname_r(int fd, char* buffer, ssize_t size)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(tty);
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!validate_write(buffer, size))
|
if (!validate_write(buffer, size))
|
||||||
|
@ -1296,6 +1332,7 @@ int Process::sys$ttyname_r(int fd, char* buffer, ssize_t size)
|
||||||
|
|
||||||
int Process::sys$ptsname_r(int fd, char* buffer, ssize_t size)
|
int Process::sys$ptsname_r(int fd, char* buffer, ssize_t size)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(tty);
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!validate_write(buffer, size))
|
if (!validate_write(buffer, size))
|
||||||
|
@ -1315,6 +1352,7 @@ int Process::sys$ptsname_r(int fd, char* buffer, ssize_t size)
|
||||||
|
|
||||||
ssize_t Process::sys$writev(int fd, const struct iovec* iov, int iov_count)
|
ssize_t Process::sys$writev(int fd, const struct iovec* iov, int iov_count)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (iov_count < 0)
|
if (iov_count < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -1400,6 +1438,7 @@ ssize_t Process::do_write(FileDescription& description, const u8* data, int data
|
||||||
|
|
||||||
ssize_t Process::sys$write(int fd, const u8* data, ssize_t size)
|
ssize_t Process::sys$write(int fd, const u8* data, ssize_t size)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
|
@ -1420,6 +1459,7 @@ ssize_t Process::sys$write(int fd, const u8* data, ssize_t size)
|
||||||
|
|
||||||
ssize_t Process::sys$read(int fd, u8* buffer, ssize_t size)
|
ssize_t Process::sys$read(int fd, u8* buffer, ssize_t size)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
|
@ -1447,6 +1487,7 @@ ssize_t Process::sys$read(int fd, u8* buffer, ssize_t size)
|
||||||
|
|
||||||
int Process::sys$close(int fd)
|
int Process::sys$close(int fd)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
auto description = file_description(fd);
|
auto description = file_description(fd);
|
||||||
#ifdef DEBUG_IO
|
#ifdef DEBUG_IO
|
||||||
dbgprintf("%s(%u) sys$close(%d) %p\n", name().characters(), pid(), fd, description.ptr());
|
dbgprintf("%s(%u) sys$close(%d) %p\n", name().characters(), pid(), fd, description.ptr());
|
||||||
|
@ -1460,6 +1501,7 @@ int Process::sys$close(int fd)
|
||||||
|
|
||||||
int Process::sys$utime(const char* user_path, size_t path_length, const utimbuf* user_buf)
|
int Process::sys$utime(const char* user_path, size_t path_length, const utimbuf* user_buf)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(fattr);
|
||||||
if (user_buf && !validate_read_typed(user_buf))
|
if (user_buf && !validate_read_typed(user_buf))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
auto path = get_syscall_path_argument(user_path, path_length);
|
auto path = get_syscall_path_argument(user_path, path_length);
|
||||||
|
@ -1477,6 +1519,7 @@ int Process::sys$utime(const char* user_path, size_t path_length, const utimbuf*
|
||||||
|
|
||||||
int Process::sys$access(const char* user_path, size_t path_length, int mode)
|
int Process::sys$access(const char* user_path, size_t path_length, int mode)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(rpath);
|
||||||
auto path = get_syscall_path_argument(user_path, path_length);
|
auto path = get_syscall_path_argument(user_path, path_length);
|
||||||
if (path.is_error())
|
if (path.is_error())
|
||||||
return path.error();
|
return path.error();
|
||||||
|
@ -1485,6 +1528,7 @@ int Process::sys$access(const char* user_path, size_t path_length, int mode)
|
||||||
|
|
||||||
int Process::sys$fcntl(int fd, int cmd, u32 arg)
|
int Process::sys$fcntl(int fd, int cmd, u32 arg)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
(void)cmd;
|
(void)cmd;
|
||||||
(void)arg;
|
(void)arg;
|
||||||
dbgprintf("sys$fcntl: fd=%d, cmd=%d, arg=%u\n", fd, cmd, arg);
|
dbgprintf("sys$fcntl: fd=%d, cmd=%d, arg=%u\n", fd, cmd, arg);
|
||||||
|
@ -1522,6 +1566,7 @@ int Process::sys$fcntl(int fd, int cmd, u32 arg)
|
||||||
|
|
||||||
int Process::sys$fstat(int fd, stat* statbuf)
|
int Process::sys$fstat(int fd, stat* statbuf)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (!validate_write_typed(statbuf))
|
if (!validate_write_typed(statbuf))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
auto description = file_description(fd);
|
auto description = file_description(fd);
|
||||||
|
@ -1532,6 +1577,7 @@ int Process::sys$fstat(int fd, stat* statbuf)
|
||||||
|
|
||||||
int Process::sys$lstat(const char* user_path, size_t path_length, stat* user_statbuf)
|
int Process::sys$lstat(const char* user_path, size_t path_length, stat* user_statbuf)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(rpath);
|
||||||
if (!validate_write_typed(user_statbuf))
|
if (!validate_write_typed(user_statbuf))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
auto path = get_syscall_path_argument(user_path, path_length);
|
auto path = get_syscall_path_argument(user_path, path_length);
|
||||||
|
@ -1550,6 +1596,7 @@ int Process::sys$lstat(const char* user_path, size_t path_length, stat* user_sta
|
||||||
|
|
||||||
int Process::sys$stat(const char* user_path, size_t path_length, stat* user_statbuf)
|
int Process::sys$stat(const char* user_path, size_t path_length, stat* user_statbuf)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(rpath);
|
||||||
if (!validate_write_typed(user_statbuf))
|
if (!validate_write_typed(user_statbuf))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
auto path = get_syscall_path_argument(user_path, path_length);
|
auto path = get_syscall_path_argument(user_path, path_length);
|
||||||
|
@ -1594,6 +1641,7 @@ String Process::validate_and_copy_string_from_user(const Syscall::StringArgument
|
||||||
|
|
||||||
int Process::sys$readlink(const Syscall::SC_readlink_params* user_params)
|
int Process::sys$readlink(const Syscall::SC_readlink_params* user_params)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(rpath);
|
||||||
if (!validate_read_typed(user_params))
|
if (!validate_read_typed(user_params))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
Syscall::SC_readlink_params params;
|
Syscall::SC_readlink_params params;
|
||||||
|
@ -1627,6 +1675,7 @@ int Process::sys$readlink(const Syscall::SC_readlink_params* user_params)
|
||||||
|
|
||||||
int Process::sys$chdir(const char* user_path, size_t path_length)
|
int Process::sys$chdir(const char* user_path, size_t path_length)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(rpath);
|
||||||
auto path = get_syscall_path_argument(user_path, path_length);
|
auto path = get_syscall_path_argument(user_path, path_length);
|
||||||
if (path.is_error())
|
if (path.is_error())
|
||||||
return path.error();
|
return path.error();
|
||||||
|
@ -1639,6 +1688,7 @@ int Process::sys$chdir(const char* user_path, size_t path_length)
|
||||||
|
|
||||||
int Process::sys$fchdir(int fd)
|
int Process::sys$fchdir(int fd)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
auto description = file_description(fd);
|
auto description = file_description(fd);
|
||||||
if (!description)
|
if (!description)
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
|
@ -1655,6 +1705,7 @@ int Process::sys$fchdir(int fd)
|
||||||
|
|
||||||
int Process::sys$getcwd(char* buffer, ssize_t size)
|
int Process::sys$getcwd(char* buffer, ssize_t size)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(rpath);
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!validate_write(buffer, size))
|
if (!validate_write(buffer, size))
|
||||||
|
@ -1686,6 +1737,14 @@ int Process::sys$open(const Syscall::SC_open_params* user_params)
|
||||||
auto options = params.options;
|
auto options = params.options;
|
||||||
auto mode = params.mode;
|
auto mode = params.mode;
|
||||||
|
|
||||||
|
if ((options & O_RDWR) || (options & O_WRONLY))
|
||||||
|
REQUIRE_PROMISE(wpath);
|
||||||
|
else
|
||||||
|
REQUIRE_PROMISE(rpath);
|
||||||
|
|
||||||
|
if (options & O_CREAT)
|
||||||
|
REQUIRE_PROMISE(cpath);
|
||||||
|
|
||||||
auto path = get_syscall_path_argument(params.path);
|
auto path = get_syscall_path_argument(params.path);
|
||||||
if (path.is_error())
|
if (path.is_error())
|
||||||
return path.error();
|
return path.error();
|
||||||
|
@ -1721,6 +1780,14 @@ int Process::sys$openat(const Syscall::SC_openat_params* user_params)
|
||||||
int options = params.options;
|
int options = params.options;
|
||||||
u16 mode = params.mode;
|
u16 mode = params.mode;
|
||||||
|
|
||||||
|
if ((options & O_RDWR) || (options & O_WRONLY))
|
||||||
|
REQUIRE_PROMISE(wpath);
|
||||||
|
else
|
||||||
|
REQUIRE_PROMISE(rpath);
|
||||||
|
|
||||||
|
if (options & O_CREAT)
|
||||||
|
REQUIRE_PROMISE(cpath);
|
||||||
|
|
||||||
// Ignore everything except permission bits.
|
// Ignore everything except permission bits.
|
||||||
mode &= 04777;
|
mode &= 04777;
|
||||||
|
|
||||||
|
@ -1773,6 +1840,7 @@ int Process::alloc_fd(int first_candidate_fd)
|
||||||
|
|
||||||
int Process::sys$pipe(int pipefd[2], int flags)
|
int Process::sys$pipe(int pipefd[2], int flags)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (!validate_write_typed(pipefd))
|
if (!validate_write_typed(pipefd))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (number_of_open_file_descriptors() + 2 > max_open_file_descriptors())
|
if (number_of_open_file_descriptors() + 2 > max_open_file_descriptors())
|
||||||
|
@ -1799,6 +1867,7 @@ int Process::sys$pipe(int pipefd[2], int flags)
|
||||||
|
|
||||||
int Process::sys$killpg(int pgrp, int signum)
|
int Process::sys$killpg(int pgrp, int signum)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(proc);
|
||||||
if (signum < 1 || signum >= 32)
|
if (signum < 1 || signum >= 32)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (pgrp < 0)
|
if (pgrp < 0)
|
||||||
|
@ -1810,6 +1879,7 @@ int Process::sys$killpg(int pgrp, int signum)
|
||||||
|
|
||||||
int Process::sys$setuid(uid_t uid)
|
int Process::sys$setuid(uid_t uid)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(id);
|
||||||
if (uid != m_uid && !is_superuser())
|
if (uid != m_uid && !is_superuser())
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
m_uid = uid;
|
m_uid = uid;
|
||||||
|
@ -1819,6 +1889,7 @@ int Process::sys$setuid(uid_t uid)
|
||||||
|
|
||||||
int Process::sys$setgid(gid_t gid)
|
int Process::sys$setgid(gid_t gid)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(id);
|
||||||
if (gid != m_gid && !is_superuser())
|
if (gid != m_gid && !is_superuser())
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
m_gid = gid;
|
m_gid = gid;
|
||||||
|
@ -1828,6 +1899,7 @@ int Process::sys$setgid(gid_t gid)
|
||||||
|
|
||||||
unsigned Process::sys$alarm(unsigned seconds)
|
unsigned Process::sys$alarm(unsigned seconds)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
unsigned previous_alarm_remaining = 0;
|
unsigned previous_alarm_remaining = 0;
|
||||||
if (m_alarm_deadline && m_alarm_deadline > g_uptime) {
|
if (m_alarm_deadline && m_alarm_deadline > g_uptime) {
|
||||||
previous_alarm_remaining = (m_alarm_deadline - g_uptime) / TICKS_PER_SECOND;
|
previous_alarm_remaining = (m_alarm_deadline - g_uptime) / TICKS_PER_SECOND;
|
||||||
|
@ -1842,6 +1914,7 @@ unsigned Process::sys$alarm(unsigned seconds)
|
||||||
|
|
||||||
int Process::sys$uname(utsname* buf)
|
int Process::sys$uname(utsname* buf)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (!validate_write_typed(buf))
|
if (!validate_write_typed(buf))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
LOCKER(*s_hostname_lock);
|
LOCKER(*s_hostname_lock);
|
||||||
|
@ -1905,6 +1978,7 @@ KResult Process::do_killpg(pid_t pgrp, int signal)
|
||||||
|
|
||||||
int Process::sys$kill(pid_t pid, int signal)
|
int Process::sys$kill(pid_t pid, int signal)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(proc);
|
||||||
if (signal < 0 || signal >= 32)
|
if (signal < 0 || signal >= 32)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (pid <= 0)
|
if (pid <= 0)
|
||||||
|
@ -1931,6 +2005,7 @@ int Process::sys$kill(pid_t pid, int signal)
|
||||||
|
|
||||||
int Process::sys$usleep(useconds_t usec)
|
int Process::sys$usleep(useconds_t usec)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (!usec)
|
if (!usec)
|
||||||
return 0;
|
return 0;
|
||||||
u64 wakeup_time = current->sleep(usec / 1000);
|
u64 wakeup_time = current->sleep(usec / 1000);
|
||||||
|
@ -1941,6 +2016,7 @@ int Process::sys$usleep(useconds_t usec)
|
||||||
|
|
||||||
int Process::sys$sleep(unsigned seconds)
|
int Process::sys$sleep(unsigned seconds)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (!seconds)
|
if (!seconds)
|
||||||
return 0;
|
return 0;
|
||||||
u64 wakeup_time = current->sleep(seconds * TICKS_PER_SECOND);
|
u64 wakeup_time = current->sleep(seconds * TICKS_PER_SECOND);
|
||||||
|
@ -1963,6 +2039,7 @@ void kgettimeofday(timeval& tv)
|
||||||
|
|
||||||
int Process::sys$gettimeofday(timeval* tv)
|
int Process::sys$gettimeofday(timeval* tv)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (!validate_write_typed(tv))
|
if (!validate_write_typed(tv))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
*tv = kgettimeofday();
|
*tv = kgettimeofday();
|
||||||
|
@ -1971,36 +2048,43 @@ int Process::sys$gettimeofday(timeval* tv)
|
||||||
|
|
||||||
uid_t Process::sys$getuid()
|
uid_t Process::sys$getuid()
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
return m_uid;
|
return m_uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
gid_t Process::sys$getgid()
|
gid_t Process::sys$getgid()
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
return m_gid;
|
return m_gid;
|
||||||
}
|
}
|
||||||
|
|
||||||
uid_t Process::sys$geteuid()
|
uid_t Process::sys$geteuid()
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
return m_euid;
|
return m_euid;
|
||||||
}
|
}
|
||||||
|
|
||||||
gid_t Process::sys$getegid()
|
gid_t Process::sys$getegid()
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
return m_egid;
|
return m_egid;
|
||||||
}
|
}
|
||||||
|
|
||||||
pid_t Process::sys$getpid()
|
pid_t Process::sys$getpid()
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
return m_pid;
|
return m_pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
pid_t Process::sys$getppid()
|
pid_t Process::sys$getppid()
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
return m_ppid;
|
return m_ppid;
|
||||||
}
|
}
|
||||||
|
|
||||||
mode_t Process::sys$umask(mode_t mask)
|
mode_t Process::sys$umask(mode_t mask)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
auto old_mask = m_umask;
|
auto old_mask = m_umask;
|
||||||
m_umask = mask & 0777;
|
m_umask = mask & 0777;
|
||||||
return old_mask;
|
return old_mask;
|
||||||
|
@ -2031,6 +2115,7 @@ int Process::reap(Process& process)
|
||||||
|
|
||||||
pid_t Process::sys$waitpid(pid_t waitee, int* wstatus, int options)
|
pid_t Process::sys$waitpid(pid_t waitee, int* wstatus, int options)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
dbgprintf("sys$waitpid(%d, %p, %d)\n", waitee, wstatus, options);
|
dbgprintf("sys$waitpid(%d, %p, %d)\n", waitee, wstatus, options);
|
||||||
|
|
||||||
if (!options) {
|
if (!options) {
|
||||||
|
@ -2139,6 +2224,7 @@ bool Process::validate_write(void* address, ssize_t size) const
|
||||||
|
|
||||||
pid_t Process::sys$getsid(pid_t pid)
|
pid_t Process::sys$getsid(pid_t pid)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
return m_sid;
|
return m_sid;
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
|
@ -2152,6 +2238,7 @@ pid_t Process::sys$getsid(pid_t pid)
|
||||||
|
|
||||||
pid_t Process::sys$setsid()
|
pid_t Process::sys$setsid()
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(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(), [&](auto&) {
|
Process::for_each_in_pgrp(pid(), [&](auto&) {
|
||||||
|
@ -2167,6 +2254,7 @@ pid_t Process::sys$setsid()
|
||||||
|
|
||||||
pid_t Process::sys$getpgid(pid_t pid)
|
pid_t Process::sys$getpgid(pid_t pid)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
return m_pgid;
|
return m_pgid;
|
||||||
InterruptDisabler disabler; // FIXME: Use a ProcessHandle
|
InterruptDisabler disabler; // FIXME: Use a ProcessHandle
|
||||||
|
@ -2178,6 +2266,7 @@ pid_t Process::sys$getpgid(pid_t pid)
|
||||||
|
|
||||||
pid_t Process::sys$getpgrp()
|
pid_t Process::sys$getpgrp()
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
return m_pgid;
|
return m_pgid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2192,6 +2281,7 @@ static pid_t get_sid_from_pgid(pid_t pgid)
|
||||||
|
|
||||||
int Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
|
int Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(proc);
|
||||||
InterruptDisabler disabler; // FIXME: Use a ProcessHandle
|
InterruptDisabler disabler; // FIXME: Use a ProcessHandle
|
||||||
pid_t pid = specified_pid ? specified_pid : m_pid;
|
pid_t pid = specified_pid ? specified_pid : m_pid;
|
||||||
if (specified_pgid < 0) {
|
if (specified_pgid < 0) {
|
||||||
|
@ -2240,11 +2330,13 @@ int Process::sys$ioctl(int fd, unsigned request, unsigned arg)
|
||||||
|
|
||||||
int Process::sys$getdtablesize()
|
int Process::sys$getdtablesize()
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
return m_max_open_file_descriptors;
|
return m_max_open_file_descriptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Process::sys$dup(int old_fd)
|
int Process::sys$dup(int old_fd)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
auto description = file_description(old_fd);
|
auto description = file_description(old_fd);
|
||||||
if (!description)
|
if (!description)
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
|
@ -2257,6 +2349,7 @@ int Process::sys$dup(int old_fd)
|
||||||
|
|
||||||
int Process::sys$dup2(int old_fd, int new_fd)
|
int Process::sys$dup2(int old_fd, int new_fd)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
auto description = file_description(old_fd);
|
auto description = file_description(old_fd);
|
||||||
if (!description)
|
if (!description)
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
|
@ -2268,6 +2361,7 @@ int Process::sys$dup2(int old_fd, int new_fd)
|
||||||
|
|
||||||
int Process::sys$sigprocmask(int how, const sigset_t* set, sigset_t* old_set)
|
int Process::sys$sigprocmask(int how, const sigset_t* set, sigset_t* old_set)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (old_set) {
|
if (old_set) {
|
||||||
if (!validate_write_typed(old_set))
|
if (!validate_write_typed(old_set))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -2297,6 +2391,7 @@ int Process::sys$sigprocmask(int how, const sigset_t* set, sigset_t* old_set)
|
||||||
|
|
||||||
int Process::sys$sigpending(sigset_t* set)
|
int Process::sys$sigpending(sigset_t* set)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (!validate_write_typed(set))
|
if (!validate_write_typed(set))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
copy_to_user(set, ¤t->m_pending_signals, sizeof(current->m_pending_signals));
|
copy_to_user(set, ¤t->m_pending_signals, sizeof(current->m_pending_signals));
|
||||||
|
@ -2305,6 +2400,7 @@ int Process::sys$sigpending(sigset_t* set)
|
||||||
|
|
||||||
int Process::sys$sigaction(int signum, const sigaction* act, sigaction* old_act)
|
int Process::sys$sigaction(int signum, const sigaction* act, sigaction* old_act)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (signum < 1 || signum >= 32 || signum == SIGKILL || signum == SIGSTOP)
|
if (signum < 1 || signum >= 32 || signum == SIGKILL || signum == SIGSTOP)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!validate_read_typed(act))
|
if (!validate_read_typed(act))
|
||||||
|
@ -2324,6 +2420,7 @@ int Process::sys$sigaction(int signum, const sigaction* act, sigaction* old_act)
|
||||||
|
|
||||||
int Process::sys$getgroups(ssize_t count, gid_t* gids)
|
int Process::sys$getgroups(ssize_t count, gid_t* gids)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!count)
|
if (!count)
|
||||||
|
@ -2341,6 +2438,7 @@ int Process::sys$getgroups(ssize_t count, gid_t* gids)
|
||||||
|
|
||||||
int Process::sys$setgroups(ssize_t count, const gid_t* gids)
|
int Process::sys$setgroups(ssize_t count, const gid_t* gids)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(id);
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
|
@ -2359,6 +2457,7 @@ int Process::sys$setgroups(ssize_t count, const gid_t* gids)
|
||||||
|
|
||||||
int Process::sys$mkdir(const char* user_path, size_t path_length, mode_t mode)
|
int Process::sys$mkdir(const char* user_path, size_t path_length, mode_t mode)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(cpath);
|
||||||
auto path = get_syscall_path_argument(user_path, path_length);
|
auto path = get_syscall_path_argument(user_path, path_length);
|
||||||
if (path.is_error())
|
if (path.is_error())
|
||||||
return path.error();
|
return path.error();
|
||||||
|
@ -2367,6 +2466,7 @@ int Process::sys$mkdir(const char* user_path, size_t path_length, mode_t mode)
|
||||||
|
|
||||||
int Process::sys$realpath(const Syscall::SC_realpath_params* user_params)
|
int Process::sys$realpath(const Syscall::SC_realpath_params* user_params)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(rpath);
|
||||||
if (!validate_read_typed(user_params))
|
if (!validate_read_typed(user_params))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
@ -2401,6 +2501,7 @@ int Process::sys$realpath(const Syscall::SC_realpath_params* user_params)
|
||||||
|
|
||||||
clock_t Process::sys$times(tms* times)
|
clock_t Process::sys$times(tms* times)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (!validate_write_typed(times))
|
if (!validate_write_typed(times))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
copy_to_user(×->tms_utime, &m_ticks_in_user, sizeof(m_ticks_in_user));
|
copy_to_user(×->tms_utime, &m_ticks_in_user, sizeof(m_ticks_in_user));
|
||||||
|
@ -2412,6 +2513,7 @@ clock_t Process::sys$times(tms* times)
|
||||||
|
|
||||||
int Process::sys$select(const Syscall::SC_select_params* params)
|
int Process::sys$select(const Syscall::SC_select_params* params)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
// FIXME: Return -EINVAL if timeout is invalid.
|
// FIXME: Return -EINVAL if timeout is invalid.
|
||||||
if (!validate_read_typed(params))
|
if (!validate_read_typed(params))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -2498,6 +2600,7 @@ int Process::sys$select(const Syscall::SC_select_params* params)
|
||||||
|
|
||||||
int Process::sys$poll(pollfd* fds, int nfds, int timeout)
|
int Process::sys$poll(pollfd* fds, int nfds, int timeout)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (!validate_read_typed(fds))
|
if (!validate_read_typed(fds))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
@ -2567,6 +2670,7 @@ Custody& Process::current_directory()
|
||||||
|
|
||||||
int Process::sys$link(const Syscall::SC_link_params* user_params)
|
int Process::sys$link(const Syscall::SC_link_params* user_params)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(cpath);
|
||||||
if (!validate_read_typed(user_params))
|
if (!validate_read_typed(user_params))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
Syscall::SC_link_params params;
|
Syscall::SC_link_params params;
|
||||||
|
@ -2580,6 +2684,7 @@ int Process::sys$link(const Syscall::SC_link_params* user_params)
|
||||||
|
|
||||||
int Process::sys$unlink(const char* user_path, size_t path_length)
|
int Process::sys$unlink(const char* user_path, size_t path_length)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(cpath);
|
||||||
if (!validate_read(user_path, path_length))
|
if (!validate_read(user_path, path_length))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
auto path = get_syscall_path_argument(user_path, path_length);
|
auto path = get_syscall_path_argument(user_path, path_length);
|
||||||
|
@ -2590,6 +2695,7 @@ int Process::sys$unlink(const char* user_path, size_t path_length)
|
||||||
|
|
||||||
int Process::sys$symlink(const Syscall::SC_symlink_params* user_params)
|
int Process::sys$symlink(const Syscall::SC_symlink_params* user_params)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(cpath);
|
||||||
if (!validate_read_typed(user_params))
|
if (!validate_read_typed(user_params))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
Syscall::SC_symlink_params params;
|
Syscall::SC_symlink_params params;
|
||||||
|
@ -2621,6 +2727,7 @@ KResultOr<String> Process::get_syscall_path_argument(const Syscall::StringArgume
|
||||||
|
|
||||||
int Process::sys$rmdir(const char* user_path, size_t path_length)
|
int Process::sys$rmdir(const char* user_path, size_t path_length)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(cpath);
|
||||||
auto path = get_syscall_path_argument(user_path, path_length);
|
auto path = get_syscall_path_argument(user_path, path_length);
|
||||||
if (path.is_error())
|
if (path.is_error())
|
||||||
return path.error();
|
return path.error();
|
||||||
|
@ -2629,6 +2736,7 @@ int Process::sys$rmdir(const char* user_path, size_t path_length)
|
||||||
|
|
||||||
int Process::sys$chmod(const char* user_path, size_t path_length, mode_t mode)
|
int Process::sys$chmod(const char* user_path, size_t path_length, mode_t mode)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(fattr);
|
||||||
auto path = get_syscall_path_argument(user_path, path_length);
|
auto path = get_syscall_path_argument(user_path, path_length);
|
||||||
if (path.is_error())
|
if (path.is_error())
|
||||||
return path.error();
|
return path.error();
|
||||||
|
@ -2637,6 +2745,7 @@ int Process::sys$chmod(const char* user_path, size_t path_length, mode_t mode)
|
||||||
|
|
||||||
int Process::sys$fchmod(int fd, mode_t mode)
|
int Process::sys$fchmod(int fd, mode_t mode)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(fattr);
|
||||||
auto description = file_description(fd);
|
auto description = file_description(fd);
|
||||||
if (!description)
|
if (!description)
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
|
@ -2645,6 +2754,7 @@ int Process::sys$fchmod(int fd, mode_t mode)
|
||||||
|
|
||||||
int Process::sys$fchown(int fd, uid_t uid, gid_t gid)
|
int Process::sys$fchown(int fd, uid_t uid, gid_t gid)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(chown);
|
||||||
auto description = file_description(fd);
|
auto description = file_description(fd);
|
||||||
if (!description)
|
if (!description)
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
|
@ -2653,6 +2763,7 @@ int Process::sys$fchown(int fd, uid_t uid, gid_t gid)
|
||||||
|
|
||||||
int Process::sys$chown(const Syscall::SC_chown_params* user_params)
|
int Process::sys$chown(const Syscall::SC_chown_params* user_params)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(chown);
|
||||||
if (!validate_read_typed(user_params))
|
if (!validate_read_typed(user_params))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
Syscall::SC_chown_params params;
|
Syscall::SC_chown_params params;
|
||||||
|
@ -2790,8 +2901,18 @@ size_t Process::amount_purgeable_nonvolatile() const
|
||||||
return amount;
|
return amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(domain) \
|
||||||
|
do { \
|
||||||
|
if (domain == AF_INET) \
|
||||||
|
REQUIRE_PROMISE(inet); \
|
||||||
|
else if (domain == AF_LOCAL) \
|
||||||
|
REQUIRE_PROMISE(unix); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
int Process::sys$socket(int domain, int type, int protocol)
|
int Process::sys$socket(int domain, int type, int protocol)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(domain);
|
||||||
|
|
||||||
if ((type & SOCK_TYPE_MASK) == SOCK_RAW && !is_superuser())
|
if ((type & SOCK_TYPE_MASK) == SOCK_RAW && !is_superuser())
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
int fd = alloc_fd();
|
int fd = alloc_fd();
|
||||||
|
@ -2822,6 +2943,7 @@ int Process::sys$bind(int sockfd, const sockaddr* address, socklen_t address_len
|
||||||
if (!description->is_socket())
|
if (!description->is_socket())
|
||||||
return -ENOTSOCK;
|
return -ENOTSOCK;
|
||||||
auto& socket = *description->socket();
|
auto& socket = *description->socket();
|
||||||
|
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
||||||
return socket.bind(address, address_length);
|
return socket.bind(address, address_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2833,6 +2955,7 @@ int Process::sys$listen(int sockfd, int backlog)
|
||||||
if (!description->is_socket())
|
if (!description->is_socket())
|
||||||
return -ENOTSOCK;
|
return -ENOTSOCK;
|
||||||
auto& socket = *description->socket();
|
auto& socket = *description->socket();
|
||||||
|
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
||||||
if (socket.is_connected())
|
if (socket.is_connected())
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
return socket.listen(backlog);
|
return socket.listen(backlog);
|
||||||
|
@ -2854,6 +2977,7 @@ int Process::sys$accept(int accepting_socket_fd, sockaddr* address, socklen_t* a
|
||||||
if (!accepting_socket_description->is_socket())
|
if (!accepting_socket_description->is_socket())
|
||||||
return -ENOTSOCK;
|
return -ENOTSOCK;
|
||||||
auto& socket = *accepting_socket_description->socket();
|
auto& socket = *accepting_socket_description->socket();
|
||||||
|
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
||||||
if (!socket.can_accept()) {
|
if (!socket.can_accept()) {
|
||||||
if (accepting_socket_description->is_blocking()) {
|
if (accepting_socket_description->is_blocking()) {
|
||||||
if (current->block<Thread::AcceptBlocker>(*accepting_socket_description) != Thread::BlockResult::WokeNormally)
|
if (current->block<Thread::AcceptBlocker>(*accepting_socket_description) != Thread::BlockResult::WokeNormally)
|
||||||
|
@ -2893,6 +3017,7 @@ int Process::sys$connect(int sockfd, const sockaddr* address, socklen_t address_
|
||||||
return -ENOTSOCK;
|
return -ENOTSOCK;
|
||||||
|
|
||||||
auto& socket = *description->socket();
|
auto& socket = *description->socket();
|
||||||
|
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
||||||
SmapDisabler disabler;
|
SmapDisabler disabler;
|
||||||
return socket.connect(*description, address, address_size, description->is_blocking() ? ShouldBlock::Yes : ShouldBlock::No);
|
return socket.connect(*description, address, address_size, description->is_blocking() ? ShouldBlock::Yes : ShouldBlock::No);
|
||||||
}
|
}
|
||||||
|
@ -2920,6 +3045,7 @@ ssize_t Process::sys$sendto(const Syscall::SC_sendto_params* user_params)
|
||||||
return -ENOTSOCK;
|
return -ENOTSOCK;
|
||||||
SmapDisabler disabler;
|
SmapDisabler disabler;
|
||||||
auto& socket = *description->socket();
|
auto& socket = *description->socket();
|
||||||
|
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
||||||
return socket.sendto(*description, params.data.data, params.data.size, flags, addr, addr_length);
|
return socket.sendto(*description, params.data.data, params.data.size, flags, addr, addr_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2952,6 +3078,7 @@ ssize_t Process::sys$recvfrom(const Syscall::SC_recvfrom_params* user_params)
|
||||||
if (!description->is_socket())
|
if (!description->is_socket())
|
||||||
return -ENOTSOCK;
|
return -ENOTSOCK;
|
||||||
auto& socket = *description->socket();
|
auto& socket = *description->socket();
|
||||||
|
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
||||||
|
|
||||||
bool original_blocking = description->is_blocking();
|
bool original_blocking = description->is_blocking();
|
||||||
if (flags & MSG_DONTWAIT)
|
if (flags & MSG_DONTWAIT)
|
||||||
|
@ -2984,6 +3111,7 @@ int Process::sys$getsockname(int sockfd, sockaddr* addr, socklen_t* addrlen)
|
||||||
return -ENOTSOCK;
|
return -ENOTSOCK;
|
||||||
|
|
||||||
auto& socket = *description->socket();
|
auto& socket = *description->socket();
|
||||||
|
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
||||||
if (!socket.get_local_address(addr, addrlen))
|
if (!socket.get_local_address(addr, addrlen))
|
||||||
return -EINVAL; // FIXME: Should this be another error? I'm not sure.
|
return -EINVAL; // FIXME: Should this be another error? I'm not sure.
|
||||||
|
|
||||||
|
@ -3011,6 +3139,7 @@ int Process::sys$getpeername(int sockfd, sockaddr* addr, socklen_t* addrlen)
|
||||||
return -ENOTSOCK;
|
return -ENOTSOCK;
|
||||||
|
|
||||||
auto& socket = *description->socket();
|
auto& socket = *description->socket();
|
||||||
|
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
||||||
|
|
||||||
if (socket.setup_state() != Socket::SetupState::Completed)
|
if (socket.setup_state() != Socket::SetupState::Completed)
|
||||||
return -ENOTCONN;
|
return -ENOTCONN;
|
||||||
|
@ -3023,6 +3152,7 @@ int Process::sys$getpeername(int sockfd, sockaddr* addr, socklen_t* addrlen)
|
||||||
|
|
||||||
int Process::sys$sched_setparam(pid_t pid, const struct sched_param* param)
|
int Process::sys$sched_setparam(pid_t pid, const struct sched_param* param)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(proc);
|
||||||
if (!validate_read_typed(param))
|
if (!validate_read_typed(param))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
@ -3049,6 +3179,7 @@ int Process::sys$sched_setparam(pid_t pid, const struct sched_param* param)
|
||||||
|
|
||||||
int Process::sys$sched_getparam(pid_t pid, struct sched_param* param)
|
int Process::sys$sched_getparam(pid_t pid, struct sched_param* param)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(proc);
|
||||||
if (!validate_write_typed(param))
|
if (!validate_write_typed(param))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
@ -3092,6 +3223,7 @@ int Process::sys$getsockopt(const Syscall::SC_getsockopt_params* params)
|
||||||
if (!description->is_socket())
|
if (!description->is_socket())
|
||||||
return -ENOTSOCK;
|
return -ENOTSOCK;
|
||||||
auto& socket = *description->socket();
|
auto& socket = *description->socket();
|
||||||
|
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
||||||
return socket.getsockopt(*description, level, option, value, value_size);
|
return socket.getsockopt(*description, level, option, value, value_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3116,6 +3248,7 @@ int Process::sys$setsockopt(const Syscall::SC_setsockopt_params* params)
|
||||||
if (!description->is_socket())
|
if (!description->is_socket())
|
||||||
return -ENOTSOCK;
|
return -ENOTSOCK;
|
||||||
auto& socket = *description->socket();
|
auto& socket = *description->socket();
|
||||||
|
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
||||||
return socket.setsockopt(level, option, value, value_size);
|
return socket.setsockopt(level, option, value, value_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3131,6 +3264,7 @@ void Process::disown_all_shared_buffers()
|
||||||
|
|
||||||
int Process::sys$create_shared_buffer(int size, void** buffer)
|
int Process::sys$create_shared_buffer(int size, void** buffer)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(shared_buffer);
|
||||||
if (!size || size < 0)
|
if (!size || size < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
size = PAGE_ROUND_UP(size);
|
size = PAGE_ROUND_UP(size);
|
||||||
|
@ -3159,6 +3293,7 @@ int Process::sys$create_shared_buffer(int size, void** buffer)
|
||||||
|
|
||||||
int Process::sys$share_buffer_with(int shared_buffer_id, pid_t peer_pid)
|
int Process::sys$share_buffer_with(int shared_buffer_id, pid_t peer_pid)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(shared_buffer);
|
||||||
if (!peer_pid || peer_pid < 0 || peer_pid == m_pid)
|
if (!peer_pid || peer_pid < 0 || peer_pid == m_pid)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
LOCKER(shared_buffers().lock());
|
LOCKER(shared_buffers().lock());
|
||||||
|
@ -3180,6 +3315,7 @@ int Process::sys$share_buffer_with(int shared_buffer_id, pid_t peer_pid)
|
||||||
|
|
||||||
int Process::sys$share_buffer_globally(int shared_buffer_id)
|
int Process::sys$share_buffer_globally(int shared_buffer_id)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(shared_buffer);
|
||||||
LOCKER(shared_buffers().lock());
|
LOCKER(shared_buffers().lock());
|
||||||
auto it = shared_buffers().resource().find(shared_buffer_id);
|
auto it = shared_buffers().resource().find(shared_buffer_id);
|
||||||
if (it == shared_buffers().resource().end())
|
if (it == shared_buffers().resource().end())
|
||||||
|
@ -3193,6 +3329,7 @@ int Process::sys$share_buffer_globally(int shared_buffer_id)
|
||||||
|
|
||||||
int Process::sys$release_shared_buffer(int shared_buffer_id)
|
int Process::sys$release_shared_buffer(int shared_buffer_id)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(shared_buffer);
|
||||||
LOCKER(shared_buffers().lock());
|
LOCKER(shared_buffers().lock());
|
||||||
auto it = shared_buffers().resource().find(shared_buffer_id);
|
auto it = shared_buffers().resource().find(shared_buffer_id);
|
||||||
if (it == shared_buffers().resource().end())
|
if (it == shared_buffers().resource().end())
|
||||||
|
@ -3209,6 +3346,7 @@ int Process::sys$release_shared_buffer(int shared_buffer_id)
|
||||||
|
|
||||||
void* Process::sys$get_shared_buffer(int shared_buffer_id)
|
void* Process::sys$get_shared_buffer(int shared_buffer_id)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(shared_buffer);
|
||||||
LOCKER(shared_buffers().lock());
|
LOCKER(shared_buffers().lock());
|
||||||
auto it = shared_buffers().resource().find(shared_buffer_id);
|
auto it = shared_buffers().resource().find(shared_buffer_id);
|
||||||
if (it == shared_buffers().resource().end())
|
if (it == shared_buffers().resource().end())
|
||||||
|
@ -3224,6 +3362,7 @@ void* Process::sys$get_shared_buffer(int shared_buffer_id)
|
||||||
|
|
||||||
int Process::sys$seal_shared_buffer(int shared_buffer_id)
|
int Process::sys$seal_shared_buffer(int shared_buffer_id)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(shared_buffer);
|
||||||
LOCKER(shared_buffers().lock());
|
LOCKER(shared_buffers().lock());
|
||||||
auto it = shared_buffers().resource().find(shared_buffer_id);
|
auto it = shared_buffers().resource().find(shared_buffer_id);
|
||||||
if (it == shared_buffers().resource().end())
|
if (it == shared_buffers().resource().end())
|
||||||
|
@ -3240,6 +3379,7 @@ int Process::sys$seal_shared_buffer(int shared_buffer_id)
|
||||||
|
|
||||||
int Process::sys$get_shared_buffer_size(int shared_buffer_id)
|
int Process::sys$get_shared_buffer_size(int shared_buffer_id)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(shared_buffer);
|
||||||
LOCKER(shared_buffers().lock());
|
LOCKER(shared_buffers().lock());
|
||||||
auto it = shared_buffers().resource().find(shared_buffer_id);
|
auto it = shared_buffers().resource().find(shared_buffer_id);
|
||||||
if (it == shared_buffers().resource().end())
|
if (it == shared_buffers().resource().end())
|
||||||
|
@ -3255,6 +3395,7 @@ int Process::sys$get_shared_buffer_size(int shared_buffer_id)
|
||||||
|
|
||||||
int Process::sys$set_shared_buffer_volatile(int shared_buffer_id, bool state)
|
int Process::sys$set_shared_buffer_volatile(int shared_buffer_id, bool state)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(shared_buffer);
|
||||||
LOCKER(shared_buffers().lock());
|
LOCKER(shared_buffers().lock());
|
||||||
auto it = shared_buffers().resource().find(shared_buffer_id);
|
auto it = shared_buffers().resource().find(shared_buffer_id);
|
||||||
if (it == shared_buffers().resource().end())
|
if (it == shared_buffers().resource().end())
|
||||||
|
@ -3296,6 +3437,7 @@ void Process::send_signal(u8 signal, Process* sender)
|
||||||
|
|
||||||
int Process::sys$create_thread(void* (*entry)(void*), void* argument, const Syscall::SC_create_thread_params* params)
|
int Process::sys$create_thread(void* (*entry)(void*), void* argument, const Syscall::SC_create_thread_params* params)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(thread);
|
||||||
if (!validate_read((const void*)entry, sizeof(void*)))
|
if (!validate_read((const void*)entry, sizeof(void*)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
@ -3357,6 +3499,7 @@ int Process::sys$create_thread(void* (*entry)(void*), void* argument, const Sysc
|
||||||
|
|
||||||
void Process::sys$exit_thread(void* exit_value)
|
void Process::sys$exit_thread(void* exit_value)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(thread);
|
||||||
cli();
|
cli();
|
||||||
current->m_exit_value = exit_value;
|
current->m_exit_value = exit_value;
|
||||||
current->set_should_die();
|
current->set_should_die();
|
||||||
|
@ -3367,6 +3510,7 @@ void Process::sys$exit_thread(void* exit_value)
|
||||||
|
|
||||||
int Process::sys$detach_thread(int tid)
|
int Process::sys$detach_thread(int tid)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(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;
|
||||||
|
@ -3380,6 +3524,7 @@ int Process::sys$detach_thread(int tid)
|
||||||
|
|
||||||
int Process::sys$join_thread(int tid, void** exit_value)
|
int Process::sys$join_thread(int tid, void** exit_value)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(thread);
|
||||||
if (exit_value && !validate_write_typed(exit_value))
|
if (exit_value && !validate_write_typed(exit_value))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
@ -3425,6 +3570,7 @@ int Process::sys$join_thread(int tid, void** exit_value)
|
||||||
|
|
||||||
int Process::sys$set_thread_name(int tid, const char* user_name, size_t user_name_length)
|
int Process::sys$set_thread_name(int tid, const char* user_name, size_t user_name_length)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(thread);
|
||||||
auto name = validate_and_copy_string_from_user(user_name, user_name_length);
|
auto name = validate_and_copy_string_from_user(user_name, user_name_length);
|
||||||
if (name.is_null())
|
if (name.is_null())
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -3442,6 +3588,7 @@ int Process::sys$set_thread_name(int tid, const char* user_name, size_t user_nam
|
||||||
}
|
}
|
||||||
int Process::sys$get_thread_name(int tid, char* buffer, size_t buffer_size)
|
int Process::sys$get_thread_name(int tid, char* buffer, size_t buffer_size)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(thread);
|
||||||
if (buffer_size == 0)
|
if (buffer_size == 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -3461,11 +3608,13 @@ int Process::sys$get_thread_name(int tid, char* buffer, size_t buffer_size)
|
||||||
|
|
||||||
int Process::sys$gettid()
|
int Process::sys$gettid()
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
return current->tid();
|
return current->tid();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Process::sys$donate(int tid)
|
int Process::sys$donate(int tid)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (tid < 0)
|
if (tid < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
|
@ -3478,6 +3627,7 @@ int Process::sys$donate(int tid)
|
||||||
|
|
||||||
int Process::sys$rename(const Syscall::SC_rename_params* user_params)
|
int Process::sys$rename(const Syscall::SC_rename_params* user_params)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(cpath);
|
||||||
if (!validate_read_typed(user_params))
|
if (!validate_read_typed(user_params))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
Syscall::SC_rename_params params;
|
Syscall::SC_rename_params params;
|
||||||
|
@ -3493,6 +3643,7 @@ int Process::sys$rename(const Syscall::SC_rename_params* user_params)
|
||||||
|
|
||||||
int Process::sys$ftruncate(int fd, off_t length)
|
int Process::sys$ftruncate(int fd, off_t length)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (length < 0)
|
if (length < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
auto description = file_description(fd);
|
auto description = file_description(fd);
|
||||||
|
@ -3505,6 +3656,7 @@ int Process::sys$ftruncate(int fd, off_t length)
|
||||||
|
|
||||||
int Process::sys$watch_file(const char* user_path, size_t path_length)
|
int Process::sys$watch_file(const char* user_path, size_t path_length)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(rpath);
|
||||||
auto path = get_syscall_path_argument(user_path, path_length);
|
auto path = get_syscall_path_argument(user_path, path_length);
|
||||||
if (path.is_error())
|
if (path.is_error())
|
||||||
return path.error();
|
return path.error();
|
||||||
|
@ -3530,6 +3682,7 @@ int Process::sys$watch_file(const char* user_path, size_t path_length)
|
||||||
|
|
||||||
int Process::sys$systrace(pid_t pid)
|
int Process::sys$systrace(pid_t pid)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(proc);
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
auto* peer = Process::from_pid(pid);
|
auto* peer = Process::from_pid(pid);
|
||||||
if (!peer)
|
if (!peer)
|
||||||
|
@ -3550,6 +3703,8 @@ int Process::sys$halt()
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
|
REQUIRE_NO_PROMISES;
|
||||||
|
|
||||||
dbgprintf("acquiring FS locks...\n");
|
dbgprintf("acquiring FS locks...\n");
|
||||||
FS::lock_all();
|
FS::lock_all();
|
||||||
dbgprintf("syncing mounted filesystems...\n");
|
dbgprintf("syncing mounted filesystems...\n");
|
||||||
|
@ -3565,6 +3720,8 @@ int Process::sys$reboot()
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
|
REQUIRE_NO_PROMISES;
|
||||||
|
|
||||||
dbgprintf("acquiring FS locks...\n");
|
dbgprintf("acquiring FS locks...\n");
|
||||||
FS::lock_all();
|
FS::lock_all();
|
||||||
dbgprintf("syncing mounted filesystems...\n");
|
dbgprintf("syncing mounted filesystems...\n");
|
||||||
|
@ -3580,6 +3737,8 @@ int Process::sys$mount(const Syscall::SC_mount_params* user_params)
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
|
REQUIRE_NO_PROMISES;
|
||||||
|
|
||||||
if (!validate_read_typed(user_params))
|
if (!validate_read_typed(user_params))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
Syscall::SC_mount_params params;
|
Syscall::SC_mount_params params;
|
||||||
|
@ -3660,6 +3819,8 @@ int Process::sys$umount(const char* user_mountpoint, size_t mountpoint_length)
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
|
REQUIRE_NO_PROMISES;
|
||||||
|
|
||||||
if (!validate_read(user_mountpoint, mountpoint_length))
|
if (!validate_read(user_mountpoint, mountpoint_length))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
@ -3696,6 +3857,7 @@ void Process::FileDescriptionAndFlags::set(NonnullRefPtr<FileDescription>&& d, u
|
||||||
|
|
||||||
int Process::sys$mknod(const Syscall::SC_mknod_params* user_params)
|
int Process::sys$mknod(const Syscall::SC_mknod_params* user_params)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(dpath);
|
||||||
if (!validate_read_typed(user_params))
|
if (!validate_read_typed(user_params))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
Syscall::SC_mknod_params params;
|
Syscall::SC_mknod_params params;
|
||||||
|
@ -3745,6 +3907,7 @@ KBuffer Process::backtrace(ProcessInspectionHandle& handle) const
|
||||||
|
|
||||||
int Process::sys$set_process_icon(int icon_id)
|
int Process::sys$set_process_icon(int icon_id)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(shared_buffer);
|
||||||
LOCKER(shared_buffers().lock());
|
LOCKER(shared_buffers().lock());
|
||||||
auto it = shared_buffers().resource().find(icon_id);
|
auto it = shared_buffers().resource().find(icon_id);
|
||||||
if (it == shared_buffers().resource().end())
|
if (it == shared_buffers().resource().end())
|
||||||
|
@ -3758,6 +3921,7 @@ int Process::sys$set_process_icon(int icon_id)
|
||||||
|
|
||||||
int Process::sys$get_process_name(char* buffer, int buffer_size)
|
int Process::sys$get_process_name(char* buffer, int buffer_size)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (buffer_size <= 0)
|
if (buffer_size <= 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -3791,6 +3955,8 @@ int Process::sys$setkeymap(const Syscall::SC_setkeymap_params* params)
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
|
REQUIRE_NO_PROMISES;
|
||||||
|
|
||||||
if (!validate_read_typed(params))
|
if (!validate_read_typed(params))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
@ -3814,6 +3980,7 @@ int Process::sys$setkeymap(const Syscall::SC_setkeymap_params* params)
|
||||||
|
|
||||||
int Process::sys$clock_gettime(clockid_t clock_id, timespec* ts)
|
int Process::sys$clock_gettime(clockid_t clock_id, timespec* ts)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (!validate_write_typed(ts))
|
if (!validate_write_typed(ts))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
@ -3832,6 +3999,7 @@ int Process::sys$clock_gettime(clockid_t clock_id, timespec* ts)
|
||||||
|
|
||||||
int Process::sys$clock_nanosleep(const Syscall::SC_clock_nanosleep_params* user_params)
|
int Process::sys$clock_nanosleep(const Syscall::SC_clock_nanosleep_params* user_params)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
if (!validate_read_typed(user_params))
|
if (!validate_read_typed(user_params))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
Syscall::SC_clock_nanosleep_params params;
|
Syscall::SC_clock_nanosleep_params params;
|
||||||
|
@ -3881,6 +4049,7 @@ int Process::sys$clock_nanosleep(const Syscall::SC_clock_nanosleep_params* user_
|
||||||
|
|
||||||
int Process::sys$sync()
|
int Process::sys$sync()
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(stdio);
|
||||||
VFS::the().sync();
|
VFS::the().sync();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3906,6 +4075,8 @@ int Process::sys$module_load(const char* user_path, size_t path_length)
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
|
REQUIRE_NO_PROMISES;
|
||||||
|
|
||||||
auto path = get_syscall_path_argument(user_path, path_length);
|
auto path = get_syscall_path_argument(user_path, path_length);
|
||||||
if (path.is_error())
|
if (path.is_error())
|
||||||
return path.error();
|
return path.error();
|
||||||
|
@ -4024,6 +4195,8 @@ int Process::sys$module_unload(const char* user_name, size_t name_length)
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
|
REQUIRE_NO_PROMISES;
|
||||||
|
|
||||||
auto module_name = validate_and_copy_string_from_user(user_name, name_length);
|
auto module_name = validate_and_copy_string_from_user(user_name, name_length);
|
||||||
if (module_name.is_null())
|
if (module_name.is_null())
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -4041,6 +4214,7 @@ int Process::sys$module_unload(const char* user_name, size_t name_length)
|
||||||
|
|
||||||
int Process::sys$profiling_enable(pid_t pid)
|
int Process::sys$profiling_enable(pid_t pid)
|
||||||
{
|
{
|
||||||
|
REQUIRE_NO_PROMISES;
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
auto* process = Process::from_pid(pid);
|
auto* process = Process::from_pid(pid);
|
||||||
if (!process)
|
if (!process)
|
||||||
|
@ -4140,6 +4314,7 @@ int Process::sys$futex(const Syscall::SC_futex_params* user_params)
|
||||||
|
|
||||||
int Process::sys$set_thread_boost(int tid, int amount)
|
int Process::sys$set_thread_boost(int tid, int amount)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(proc);
|
||||||
if (amount < 0 || amount > 20)
|
if (amount < 0 || amount > 20)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
|
@ -4156,6 +4331,7 @@ int Process::sys$set_thread_boost(int tid, int amount)
|
||||||
|
|
||||||
int Process::sys$set_process_boost(pid_t pid, int amount)
|
int Process::sys$set_process_boost(pid_t pid, int amount)
|
||||||
{
|
{
|
||||||
|
REQUIRE_PROMISE(proc);
|
||||||
if (amount < 0 || amount > 20)
|
if (amount < 0 || amount > 20)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
|
@ -4172,6 +4348,7 @@ int Process::sys$chroot(const char* user_path, size_t path_length)
|
||||||
{
|
{
|
||||||
if (!is_superuser())
|
if (!is_superuser())
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
REQUIRE_PROMISE(chroot);
|
||||||
auto path = get_syscall_path_argument(user_path, path_length);
|
auto path = get_syscall_path_argument(user_path, path_length);
|
||||||
if (path.is_error())
|
if (path.is_error())
|
||||||
return path.error();
|
return path.error();
|
||||||
|
@ -4202,3 +4379,68 @@ void Process::set_root_directory(const Custody& root)
|
||||||
{
|
{
|
||||||
m_root_directory = root;
|
m_root_directory = root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Process::sys$pledge(const Syscall::SC_pledge_params* user_params)
|
||||||
|
{
|
||||||
|
if (!validate_read_typed(user_params))
|
||||||
|
return -EFAULT;
|
||||||
|
Syscall::SC_pledge_params params;
|
||||||
|
copy_from_user(¶ms, user_params);
|
||||||
|
|
||||||
|
if (params.promises.length > 1024 || params.execpromises.length > 1024)
|
||||||
|
return -E2BIG;
|
||||||
|
|
||||||
|
String promises;
|
||||||
|
if (params.promises.characters) {
|
||||||
|
promises = validate_and_copy_string_from_user(params.promises);
|
||||||
|
if (promises.is_null())
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
String execpromises;
|
||||||
|
if (params.execpromises.characters) {
|
||||||
|
execpromises = validate_and_copy_string_from_user(params.execpromises);
|
||||||
|
if (execpromises.is_null())
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto parse_pledge = [&](auto& pledge_spec, u32& mask) {
|
||||||
|
auto parts = pledge_spec.split_view(' ');
|
||||||
|
for (auto& part : parts) {
|
||||||
|
#define __ENUMERATE_PLEDGE_PROMISE(x) \
|
||||||
|
if (part == #x) { \
|
||||||
|
mask |= (1u << (u32)Pledge::x); \
|
||||||
|
continue; \
|
||||||
|
}
|
||||||
|
ENUMERATE_PLEDGE_PROMISES
|
||||||
|
#undef __ENUMERATE_PLEDGE_PROMISE
|
||||||
|
if (part == "dns") {
|
||||||
|
// "dns" is an alias for "unix" since DNS queries go via LookupServer
|
||||||
|
mask |= (1u << (u32)Pledge::unix);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!promises.is_null()) {
|
||||||
|
u32 new_promises = 0;
|
||||||
|
if (!parse_pledge(promises, new_promises))
|
||||||
|
return -EINVAL;
|
||||||
|
if (m_promises && new_promises & ~m_promises)
|
||||||
|
return -EPERM;
|
||||||
|
m_promises = new_promises;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!execpromises.is_null()) {
|
||||||
|
u32 new_execpromises = 0;
|
||||||
|
if (!parse_pledge(execpromises, new_execpromises))
|
||||||
|
return -EINVAL;
|
||||||
|
if (m_execpromises && new_execpromises & ~m_execpromises)
|
||||||
|
return -EPERM;
|
||||||
|
m_execpromises = new_execpromises;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -30,6 +30,30 @@ void kgettimeofday(timeval&);
|
||||||
|
|
||||||
extern VirtualAddress g_return_to_ring3_from_signal_trampoline;
|
extern VirtualAddress g_return_to_ring3_from_signal_trampoline;
|
||||||
|
|
||||||
|
#define ENUMERATE_PLEDGE_PROMISES \
|
||||||
|
__ENUMERATE_PLEDGE_PROMISE(stdio) \
|
||||||
|
__ENUMERATE_PLEDGE_PROMISE(rpath) \
|
||||||
|
__ENUMERATE_PLEDGE_PROMISE(wpath) \
|
||||||
|
__ENUMERATE_PLEDGE_PROMISE(cpath) \
|
||||||
|
__ENUMERATE_PLEDGE_PROMISE(dpath) \
|
||||||
|
__ENUMERATE_PLEDGE_PROMISE(inet) \
|
||||||
|
__ENUMERATE_PLEDGE_PROMISE(id) \
|
||||||
|
__ENUMERATE_PLEDGE_PROMISE(proc) \
|
||||||
|
__ENUMERATE_PLEDGE_PROMISE(exec) \
|
||||||
|
__ENUMERATE_PLEDGE_PROMISE(unix) \
|
||||||
|
__ENUMERATE_PLEDGE_PROMISE(fattr) \
|
||||||
|
__ENUMERATE_PLEDGE_PROMISE(tty) \
|
||||||
|
__ENUMERATE_PLEDGE_PROMISE(chown) \
|
||||||
|
__ENUMERATE_PLEDGE_PROMISE(chroot) \
|
||||||
|
__ENUMERATE_PLEDGE_PROMISE(thread) \
|
||||||
|
__ENUMERATE_PLEDGE_PROMISE(shared_buffer)
|
||||||
|
|
||||||
|
enum class Pledge : u32 {
|
||||||
|
#define __ENUMERATE_PLEDGE_PROMISE(x) x,
|
||||||
|
ENUMERATE_PLEDGE_PROMISES
|
||||||
|
#undef __ENUMERATE_PLEDGE_PROMISE
|
||||||
|
};
|
||||||
|
|
||||||
class Process : public InlineLinkedListNode<Process>
|
class Process : public InlineLinkedListNode<Process>
|
||||||
, public Weakable<Process> {
|
, public Weakable<Process> {
|
||||||
friend class InlineLinkedListNode<Process>;
|
friend class InlineLinkedListNode<Process>;
|
||||||
|
@ -230,6 +254,7 @@ public:
|
||||||
int sys$set_thread_boost(int tid, int amount);
|
int sys$set_thread_boost(int tid, int amount);
|
||||||
int sys$set_process_boost(pid_t, int amount);
|
int sys$set_process_boost(pid_t, int amount);
|
||||||
int sys$chroot(const char* path, size_t path_length);
|
int sys$chroot(const char* path, size_t path_length);
|
||||||
|
int sys$pledge(const Syscall::SC_pledge_params*);
|
||||||
|
|
||||||
static void initialize();
|
static void initialize();
|
||||||
|
|
||||||
|
@ -316,6 +341,9 @@ public:
|
||||||
Custody& root_directory_for_procfs();
|
Custody& root_directory_for_procfs();
|
||||||
void set_root_directory(const Custody&);
|
void set_root_directory(const Custody&);
|
||||||
|
|
||||||
|
bool has_promises() const { return m_promises; }
|
||||||
|
bool has_promised(Pledge pledge) const { return m_promises & (1u << (u32)pledge); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class MemoryManager;
|
friend class MemoryManager;
|
||||||
friend class Scheduler;
|
friend class Scheduler;
|
||||||
|
@ -407,6 +435,9 @@ private:
|
||||||
|
|
||||||
u32 m_priority_boost { 0 };
|
u32 m_priority_boost { 0 };
|
||||||
|
|
||||||
|
u32 m_promises { 0 };
|
||||||
|
u32 m_execpromises { 0 };
|
||||||
|
|
||||||
WaitQueue& futex_queue(i32*);
|
WaitQueue& futex_queue(i32*);
|
||||||
HashMap<u32, OwnPtr<WaitQueue>> m_futex_queues;
|
HashMap<u32, OwnPtr<WaitQueue>> m_futex_queues;
|
||||||
};
|
};
|
||||||
|
|
|
@ -148,7 +148,8 @@ typedef u32 socklen_t;
|
||||||
__ENUMERATE_SYSCALL(futex) \
|
__ENUMERATE_SYSCALL(futex) \
|
||||||
__ENUMERATE_SYSCALL(set_thread_boost) \
|
__ENUMERATE_SYSCALL(set_thread_boost) \
|
||||||
__ENUMERATE_SYSCALL(set_process_boost) \
|
__ENUMERATE_SYSCALL(set_process_boost) \
|
||||||
__ENUMERATE_SYSCALL(chroot)
|
__ENUMERATE_SYSCALL(chroot) \
|
||||||
|
__ENUMERATE_SYSCALL(pledge)
|
||||||
|
|
||||||
namespace Syscall {
|
namespace Syscall {
|
||||||
|
|
||||||
|
@ -360,6 +361,11 @@ struct SC_mount_params {
|
||||||
int flags;
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SC_pledge_params {
|
||||||
|
StringArgument promises;
|
||||||
|
StringArgument execpromises;
|
||||||
|
};
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
int sync();
|
int sync();
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,11 @@ uint16_t internet_checksum(const void* ptr, size_t count)
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
if (pledge("stdio id inet dns", nullptr) < 0) {
|
||||||
|
perror("pledge");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
printf("usage: ping <host>\n");
|
printf("usage: ping <host>\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -42,6 +47,11 @@ int main(int argc, char** argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pledge("stdio inet dns", nullptr) < 0) {
|
||||||
|
perror("pledge");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
struct timeval timeout {
|
struct timeval timeout {
|
||||||
1, 0
|
1, 0
|
||||||
};
|
};
|
||||||
|
@ -57,6 +67,11 @@ int main(int argc, char** argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pledge("stdio inet", nullptr) < 0) {
|
||||||
|
perror("pledge");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
pid_t pid = getpid();
|
pid_t pid = getpid();
|
||||||
|
|
||||||
sockaddr_in peer_address;
|
sockaddr_in peer_address;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue