1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 00:17:46 +00:00

Kernel: Make copy_{from,to}_user() return KResult and use TRY()

This makes EFAULT propagation flow much more naturally. :^)
This commit is contained in:
Andreas Kling 2021-09-05 17:38:37 +02:00
parent 9903f5c6ef
commit 48a0b31c47
57 changed files with 318 additions and 551 deletions

View file

@ -52,8 +52,7 @@ KResultOr<FlatPtr> Process::sys$getcwd(Userspace<char*> buffer, size_t size)
size_t ideal_size = path.length() + 1;
auto size_to_copy = min(ideal_size, size);
if (!copy_to_user(buffer, path.characters(), size_to_copy))
return EFAULT;
TRY(copy_to_user(buffer, path.characters(), size_to_copy));
// Note: we return the whole size here, not the copied size.
return ideal_size;
}

View file

@ -24,8 +24,7 @@ KResultOr<FlatPtr> Process::sys$chown(Userspace<const Syscall::SC_chown_params*>
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
REQUIRE_PROMISE(chown);
Syscall::SC_chown_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
auto path = TRY(get_syscall_path_argument(params.path));
return VirtualFileSystem::the().chown(path->view(), params.uid, params.gid, current_directory());
}

View file

@ -37,10 +37,7 @@ KResultOr<FlatPtr> Process::sys$clock_gettime(clockid_t clock_id, Userspace<time
return EINVAL;
auto ts = TimeManagement::the().current_time(clock_id).to_timespec();
if (!copy_to_user(user_ts, &ts))
return EFAULT;
return 0;
return copy_to_user(user_ts, &ts);
}
KResultOr<FlatPtr> Process::sys$clock_settime(clockid_t clock_id, Userspace<const timespec*> user_ts)
@ -71,8 +68,7 @@ KResultOr<FlatPtr> Process::sys$clock_nanosleep(Userspace<const Syscall::SC_cloc
REQUIRE_PROMISE(stdio);
Syscall::SC_clock_nanosleep_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
Optional<Time> requested_sleep = copy_time_from_user(params.requested_sleep);
if (!requested_sleep.has_value())
@ -100,8 +96,9 @@ KResultOr<FlatPtr> Process::sys$clock_nanosleep(Userspace<const Syscall::SC_cloc
Time remaining_sleep;
was_interrupted = Thread::current()->sleep(params.clock_id, requested_sleep.value(), &remaining_sleep).was_interrupted();
timespec remaining_sleep_ts = remaining_sleep.to_timespec();
if (was_interrupted && params.remaining_sleep && !copy_to_user(params.remaining_sleep, &remaining_sleep_ts))
return EFAULT;
if (was_interrupted && params.remaining_sleep) {
TRY(copy_to_user(params.remaining_sleep, &remaining_sleep_ts));
}
}
if (was_interrupted)
return EINTR;
@ -115,8 +112,7 @@ KResultOr<FlatPtr> Process::sys$adjtime(Userspace<const timeval*> user_delta, Us
timespec old_delta_ts = TimeManagement::the().remaining_epoch_time_adjustment();
timeval old_delta;
timespec_to_timeval(old_delta_ts, old_delta);
if (!copy_to_user(user_old_delta, &old_delta))
return EFAULT;
TRY(copy_to_user(user_old_delta, &old_delta));
}
if (user_delta) {

View file

@ -33,8 +33,7 @@ KResultOr<FlatPtr> Process::sys$dbgputstr(Userspace<const char*> characters, siz
if (size <= 1024) {
char buffer[1024];
if (!copy_from_user(buffer, characters, size))
return EFAULT;
TRY(copy_from_user(buffer, characters, size));
dbgputstr(buffer, size);
return size;
}

View file

@ -79,19 +79,22 @@ static KResultOr<FlatPtr> make_userspace_context_for_main_thread([[maybe_unused]
auto push_on_new_stack = [&new_sp](FlatPtr value) {
new_sp -= sizeof(FlatPtr);
Userspace<FlatPtr*> stack_ptr = new_sp;
return copy_to_user(stack_ptr, &value);
auto result = copy_to_user(stack_ptr, &value);
VERIFY(result.is_success());
};
auto push_aux_value_on_new_stack = [&new_sp](auxv_t value) {
new_sp -= sizeof(auxv_t);
Userspace<auxv_t*> stack_ptr = new_sp;
return copy_to_user(stack_ptr, &value);
auto result = copy_to_user(stack_ptr, &value);
VERIFY(result.is_success());
};
auto push_string_on_new_stack = [&new_sp](const String& string) {
new_sp -= round_up_to_power_of_two(string.length() + 1, sizeof(FlatPtr));
Userspace<FlatPtr*> stack_ptr = new_sp;
return copy_to_user(stack_ptr, string.characters(), string.length() + 1);
auto result = copy_to_user(stack_ptr, string.characters(), string.length() + 1);
VERIFY(result.is_success());
};
Vector<FlatPtr> argv_entries;
@ -329,7 +332,7 @@ static KResultOr<LoadResult> load_elf_object(NonnullOwnPtr<Memory::AddressSpace>
master_tls_size = program_header.size_in_memory();
master_tls_alignment = program_header.alignment();
if (!copy_to_user(master_tls_region->vaddr().as_ptr(), program_header.raw_data(), program_header.size_in_image())) {
if (copy_to_user(master_tls_region->vaddr().as_ptr(), program_header.raw_data(), program_header.size_in_image()).is_error()) {
ph_load_result = EFAULT;
return IterationDecision::Break;
}
@ -382,7 +385,7 @@ static KResultOr<LoadResult> load_elf_object(NonnullOwnPtr<Memory::AddressSpace>
// Accessing it would definitely be a bug.
auto page_offset = program_header.vaddr();
page_offset.mask(~PAGE_MASK);
if (!copy_to_user((u8*)region_or_error.value()->vaddr().as_ptr() + page_offset.get(), program_header.raw_data(), program_header.size_in_image())) {
if (copy_to_user((u8*)region_or_error.value()->vaddr().as_ptr() + page_offset.get(), program_header.raw_data(), program_header.size_in_image()).is_error()) {
ph_load_result = EFAULT;
return IterationDecision::Break;
}
@ -937,8 +940,7 @@ KResultOr<FlatPtr> Process::sys$execve(Userspace<const Syscall::SC_execve_params
// NOTE: Be extremely careful with allocating any kernel memory in exec().
// On success, the kernel stack will be lost.
Syscall::SC_execve_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
if (params.arguments.length > ARG_MAX || params.environment.length > ARG_MAX)
return E2BIG;
@ -961,7 +963,7 @@ KResultOr<FlatPtr> Process::sys$execve(Userspace<const Syscall::SC_execve_params
Vector<Syscall::StringArgument, 32> strings;
if (!strings.try_resize(list.length))
return false;
if (!copy_from_user(strings.data(), list.strings, size.value()))
if (copy_from_user(strings.data(), list.strings, size.value()).is_error())
return false;
for (size_t i = 0; i < list.length; ++i) {
auto string_or_error = try_copy_kstring_from_user(strings[i]);

View file

@ -14,8 +14,7 @@ KResultOr<FlatPtr> Process::sys$ftruncate(int fd, Userspace<off_t*> userspace_le
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(stdio);
off_t length;
if (!copy_from_user(&length, userspace_length))
return EFAULT;
TRY(copy_from_user(&length, userspace_length));
if (length < 0)
return EINVAL;
auto description = fds().file_description(fd);

View file

@ -26,8 +26,7 @@ KResultOr<FlatPtr> Process::sys$futex(Userspace<const Syscall::SC_futex_params*>
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
Syscall::SC_futex_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
Thread::BlockTimeout timeout;
u32 cmd = params.futex_op & FUTEX_CMD_MASK;

View file

@ -21,11 +21,8 @@ KResultOr<FlatPtr> Process::sys$get_stack_bounds(Userspace<FlatPtr*> user_stack_
FlatPtr stack_base = stack_region->range().base().get();
size_t stack_size = stack_region->size();
if (!copy_to_user(user_stack_base, &stack_base))
return EFAULT;
if (!copy_to_user(user_stack_size, &stack_size))
return EFAULT;
return 0;
TRY(copy_to_user(user_stack_base, &stack_base));
return copy_to_user(user_stack_size, &stack_size);
}
}

View file

@ -40,18 +40,20 @@ KResultOr<FlatPtr> Process::sys$getresuid(Userspace<UserID*> ruid, Userspace<Use
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(stdio);
if (!copy_to_user(ruid, &m_protected_values.uid) || !copy_to_user(euid, &m_protected_values.euid) || !copy_to_user(suid, &m_protected_values.suid))
return EFAULT;
return 0;
TRY(copy_to_user(ruid, &m_protected_values.uid));
TRY(copy_to_user(euid, &m_protected_values.euid));
TRY(copy_to_user(suid, &m_protected_values.suid));
return KSuccess;
}
KResultOr<FlatPtr> Process::sys$getresgid(Userspace<GroupID*> rgid, Userspace<GroupID*> egid, Userspace<GroupID*> sgid)
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(stdio);
if (!copy_to_user(rgid, &m_protected_values.gid) || !copy_to_user(egid, &m_protected_values.egid) || !copy_to_user(sgid, &m_protected_values.sgid))
return EFAULT;
return 0;
TRY(copy_to_user(rgid, &m_protected_values.gid));
TRY(copy_to_user(egid, &m_protected_values.egid));
TRY(copy_to_user(sgid, &m_protected_values.sgid));
return KSuccess;
}
KResultOr<FlatPtr> Process::sys$getgroups(size_t count, Userspace<gid_t*> user_gids)
@ -62,11 +64,7 @@ KResultOr<FlatPtr> Process::sys$getgroups(size_t count, Userspace<gid_t*> user_g
return extra_gids().size();
if (count != extra_gids().size())
return EINVAL;
if (!copy_to_user(user_gids, extra_gids().data(), sizeof(gid_t) * count))
return EFAULT;
return 0;
return copy_to_user(user_gids, extra_gids().data(), sizeof(gid_t) * count);
}
}

View file

@ -17,8 +17,7 @@ KResultOr<FlatPtr> Process::sys$gethostname(Userspace<char*> buffer, size_t size
return hostname().with_shared([&](const auto& name) -> KResultOr<FlatPtr> {
if (size < (name.length() + 1))
return ENAMETOOLONG;
if (!copy_to_user(buffer, name.characters(), name.length() + 1))
return EFAULT;
TRY(copy_to_user(buffer, name.characters(), name.length() + 1));
return 0;
});
}

View file

@ -48,8 +48,7 @@ KResultOr<FlatPtr> Process::sys$inode_watcher_add_watch(Userspace<const Syscall:
REQUIRE_PROMISE(rpath);
Syscall::SC_inode_watcher_add_watch_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
auto description = fds().file_description(params.fd);
if (!description)

View file

@ -20,21 +20,15 @@ KResultOr<FlatPtr> Process::sys$setkeymap(Userspace<const Syscall::SC_setkeymap_
return EPERM;
Syscall::SC_setkeymap_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
Keyboard::CharacterMapData character_map_data;
if (!copy_n_from_user(character_map_data.map, params.map, CHAR_MAP_SIZE))
return EFAULT;
if (!copy_n_from_user(character_map_data.shift_map, params.shift_map, CHAR_MAP_SIZE))
return EFAULT;
if (!copy_n_from_user(character_map_data.alt_map, params.alt_map, CHAR_MAP_SIZE))
return EFAULT;
if (!copy_n_from_user(character_map_data.altgr_map, params.altgr_map, CHAR_MAP_SIZE))
return EFAULT;
if (!copy_n_from_user(character_map_data.shift_altgr_map, params.shift_altgr_map, CHAR_MAP_SIZE))
return EFAULT;
TRY(copy_n_from_user(character_map_data.map, params.map, CHAR_MAP_SIZE));
TRY(copy_n_from_user(character_map_data.shift_map, params.shift_map, CHAR_MAP_SIZE));
TRY(copy_n_from_user(character_map_data.alt_map, params.alt_map, CHAR_MAP_SIZE));
TRY(copy_n_from_user(character_map_data.altgr_map, params.altgr_map, CHAR_MAP_SIZE));
TRY(copy_n_from_user(character_map_data.shift_altgr_map, params.shift_altgr_map, CHAR_MAP_SIZE));
auto map_name = get_syscall_path_argument(params.map_name);
if (map_name.is_error())
@ -51,30 +45,22 @@ KResultOr<FlatPtr> Process::sys$getkeymap(Userspace<const Syscall::SC_getkeymap_
VERIFY_NO_PROCESS_BIG_LOCK(this);
REQUIRE_PROMISE(getkeymap);
Syscall::SC_getkeymap_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
Syscall::SC_getkeymap_params params {};
TRY(copy_from_user(&params, user_params));
String keymap_name = HIDManagement::the().keymap_name();
const Keyboard::CharacterMapData& character_maps = HIDManagement::the().character_maps();
if (!copy_to_user(params.map, character_maps.map, CHAR_MAP_SIZE * sizeof(u32)))
return EFAULT;
if (!copy_to_user(params.shift_map, character_maps.shift_map, CHAR_MAP_SIZE * sizeof(u32)))
return EFAULT;
if (!copy_to_user(params.alt_map, character_maps.alt_map, CHAR_MAP_SIZE * sizeof(u32)))
return EFAULT;
if (!copy_to_user(params.altgr_map, character_maps.altgr_map, CHAR_MAP_SIZE * sizeof(u32)))
return EFAULT;
if (!copy_to_user(params.shift_altgr_map, character_maps.shift_altgr_map, CHAR_MAP_SIZE * sizeof(u32)))
return EFAULT;
TRY(copy_to_user(params.map, character_maps.map, CHAR_MAP_SIZE * sizeof(u32)));
TRY(copy_to_user(params.shift_map, character_maps.shift_map, CHAR_MAP_SIZE * sizeof(u32)));
TRY(copy_to_user(params.alt_map, character_maps.alt_map, CHAR_MAP_SIZE * sizeof(u32)));
TRY(copy_to_user(params.altgr_map, character_maps.altgr_map, CHAR_MAP_SIZE * sizeof(u32)));
TRY(copy_to_user(params.shift_altgr_map, character_maps.shift_altgr_map, CHAR_MAP_SIZE * sizeof(u32)));
if (params.map_name.size < keymap_name.length())
return ENAMETOOLONG;
if (!copy_to_user(params.map_name.data, keymap_name.characters(), keymap_name.length()))
return EFAULT;
return 0;
TRY(copy_to_user(params.map_name.data, keymap_name.characters(), keymap_name.length()));
return KSuccess;
}
}

View file

@ -15,8 +15,7 @@ KResultOr<FlatPtr> Process::sys$link(Userspace<const Syscall::SC_link_params*> u
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(cpath);
Syscall::SC_link_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
auto old_path = TRY(try_copy_kstring_from_user(params.old_path));
auto new_path = TRY(try_copy_kstring_from_user(params.new_path));
return VirtualFileSystem::the().link(old_path->view(), new_path->view(), current_directory());
@ -27,8 +26,7 @@ KResultOr<FlatPtr> Process::sys$symlink(Userspace<const Syscall::SC_symlink_para
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(cpath);
Syscall::SC_symlink_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
auto target = TRY(get_syscall_path_argument(params.target));
auto linkpath = TRY(get_syscall_path_argument(params.linkpath));
return VirtualFileSystem::the().symlink(target->view(), linkpath->view(), current_directory());

View file

@ -17,12 +17,9 @@ KResultOr<FlatPtr> Process::sys$lseek(int fd, Userspace<off_t*> userspace_offset
if (!description)
return EBADF;
off_t offset;
if (!copy_from_user(&offset, userspace_offset))
return EFAULT;
TRY(copy_from_user(&offset, userspace_offset));
auto seek_result = TRY(description->seek(offset, whence));
if (!copy_to_user(userspace_offset, &seek_result))
return EFAULT;
return KSuccess;
return copy_to_user(userspace_offset, &seek_result);
}
}

View file

@ -15,8 +15,7 @@ KResultOr<FlatPtr> Process::sys$mknod(Userspace<const Syscall::SC_mknod_params*>
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(dpath);
Syscall::SC_mknod_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
if (!is_superuser() && !is_regular_file(params.mode) && !is_fifo(params.mode) && !is_socket(params.mode))
return EPERM;
auto path = TRY(get_syscall_path_argument(params.path));

View file

@ -130,8 +130,7 @@ KResultOr<FlatPtr> Process::sys$mmap(Userspace<const Syscall::SC_mmap_params*> u
REQUIRE_PROMISE(stdio);
Syscall::SC_mmap_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
FlatPtr addr = params.addr;
auto size = params.size;
@ -470,8 +469,7 @@ KResultOr<FlatPtr> Process::sys$set_mmap_name(Userspace<const Syscall::SC_set_mm
REQUIRE_PROMISE(stdio);
Syscall::SC_set_mmap_name_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
if (params.name.length > PATH_MAX)
return ENAMETOOLONG;
@ -508,8 +506,7 @@ KResultOr<FlatPtr> Process::sys$mremap(Userspace<const Syscall::SC_mremap_params
REQUIRE_PROMISE(stdio);
Syscall::SC_mremap_params params {};
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
auto old_range = TRY(expand_range_to_page_boundaries((FlatPtr)params.old_address, params.old_size));

View file

@ -27,8 +27,7 @@ KResultOr<FlatPtr> Process::sys$mount(Userspace<const Syscall::SC_mount_params*>
REQUIRE_NO_PROMISES;
Syscall::SC_mount_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
auto source_fd = params.source_fd;
auto target_or_error = try_copy_kstring_from_user(params.target);

View file

@ -15,8 +15,7 @@ KResultOr<FlatPtr> Process::sys$open(Userspace<const Syscall::SC_open_params*> u
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
Syscall::SC_open_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
int dirfd = params.dirfd;
int options = params.options;

View file

@ -36,12 +36,9 @@ KResultOr<FlatPtr> Process::sys$pipe(int pipefd[2], int flags)
m_fds[reader_fd_allocation.fd].set(move(reader_description), fd_flags);
m_fds[writer_fd_allocation.fd].set(move(writer_description), fd_flags);
if (!copy_to_user(&pipefd[0], &reader_fd_allocation.fd))
return EFAULT;
if (!copy_to_user(&pipefd[1], &writer_fd_allocation.fd))
return EFAULT;
return 0;
TRY(copy_to_user(&pipefd[0], &reader_fd_allocation.fd));
TRY(copy_to_user(&pipefd[1], &writer_fd_allocation.fd));
return KSuccess;
}
}

View file

@ -13,8 +13,7 @@ KResultOr<FlatPtr> Process::sys$pledge(Userspace<const Syscall::SC_pledge_params
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
Syscall::SC_pledge_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
if (params.promises.length > 1024 || params.execpromises.length > 1024)
return E2BIG;

View file

@ -30,9 +30,7 @@ KResultOr<FlatPtr> Process::sys$get_process_name(Userspace<char*> buffer, size_t
if (m_name.length() + 1 > buffer_size)
return ENAMETOOLONG;
if (!copy_to_user(buffer, m_name.characters(), m_name.length() + 1))
return EFAULT;
return 0;
return copy_to_user(buffer, m_name.characters(), m_name.length() + 1);
}
KResultOr<FlatPtr> Process::sys$set_process_name(Userspace<const char*> user_name, size_t user_name_length)
@ -56,8 +54,7 @@ KResultOr<FlatPtr> Process::sys$set_coredump_metadata(Userspace<const Syscall::S
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
Syscall::SC_set_coredump_metadata_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
if (params.key.length == 0 || params.key.length > 16 * KiB)
return EINVAL;
if (params.value.length > 16 * KiB)

View file

@ -92,8 +92,7 @@ static KResultOr<u32> handle_ptrace(const Kernel::Syscall::SC_ptrace_params& par
if (!tracer->has_regs())
return EINVAL;
auto* regs = reinterpret_cast<PtraceRegisters*>(params.addr);
if (!copy_to_user(regs, &tracer->regs()))
return EFAULT;
TRY(copy_to_user(regs, &tracer->regs()));
break;
}
@ -102,8 +101,7 @@ static KResultOr<u32> handle_ptrace(const Kernel::Syscall::SC_ptrace_params& par
return EINVAL;
PtraceRegisters regs {};
if (!copy_from_user(&regs, (const PtraceRegisters*)params.addr))
return EFAULT;
TRY(copy_from_user(&regs, (const PtraceRegisters*)params.addr));
auto& peer_saved_registers = peer->get_register_dump_from_stack();
// Verify that the saved registers are in usermode context
@ -117,13 +115,11 @@ static KResultOr<u32> handle_ptrace(const Kernel::Syscall::SC_ptrace_params& par
case PT_PEEK: {
Kernel::Syscall::SC_ptrace_peek_params peek_params {};
if (!copy_from_user(&peek_params, reinterpret_cast<Kernel::Syscall::SC_ptrace_peek_params*>(params.addr)))
return EFAULT;
TRY(copy_from_user(&peek_params, reinterpret_cast<Kernel::Syscall::SC_ptrace_peek_params*>(params.addr)));
if (!Memory::is_user_address(VirtualAddress { peek_params.address }))
return EFAULT;
auto data = TRY(peer->process().peek_user_data(Userspace<const u32*> { (FlatPtr)peek_params.address }));
if (!copy_to_user(peek_params.out_data, &data))
return EFAULT;
TRY(copy_to_user(peek_params.out_data, &data));
break;
}
@ -134,11 +130,9 @@ static KResultOr<u32> handle_ptrace(const Kernel::Syscall::SC_ptrace_params& par
case PT_PEEKDEBUG: {
Kernel::Syscall::SC_ptrace_peek_params peek_params {};
if (!copy_from_user(&peek_params, reinterpret_cast<Kernel::Syscall::SC_ptrace_peek_params*>(params.addr)))
return EFAULT;
TRY(copy_from_user(&peek_params, reinterpret_cast<Kernel::Syscall::SC_ptrace_peek_params*>(params.addr)));
auto data = TRY(peer->peek_debug_register(reinterpret_cast<uintptr_t>(peek_params.address)));
if (!copy_to_user(peek_params.out_data, &data))
return EFAULT;
TRY(copy_to_user(peek_params.out_data, &data));
break;
}
case PT_POKEDEBUG:
@ -155,8 +149,7 @@ KResultOr<FlatPtr> Process::sys$ptrace(Userspace<const Syscall::SC_ptrace_params
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(ptrace);
Syscall::SC_ptrace_params params {};
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
auto result = handle_ptrace(params, *this);
return result.is_error() ? result.error().error() : result.value();
}
@ -173,17 +166,12 @@ bool Process::has_tracee_thread(ProcessID tracer_pid)
KResultOr<u32> Process::peek_user_data(Userspace<const u32*> address)
{
uint32_t result;
// This function can be called from the context of another
// process that called PT_PEEK
ProcessPagingScope scope(*this);
if (!copy_from_user(&result, address)) {
dbgln("Invalid address for peek_user_data: {}", address.ptr());
return EFAULT;
}
return result;
uint32_t data;
TRY(copy_from_user(&data, address));
return data;
}
KResult Process::poke_user_data(Userspace<u32*> address, u32 data)
@ -215,12 +203,7 @@ KResult Process::poke_user_data(Userspace<u32*> address, u32 data)
}
});
if (!copy_to_user(address, &data)) {
dbgln("poke_user_data: Bad address {:p}", address.ptr());
return EFAULT;
}
return KSuccess;
return copy_to_user(address, &data);
}
KResultOr<u32> Thread::peek_debug_register(u32 register_index)

View file

@ -27,8 +27,7 @@ KResultOr<FlatPtr> Process::sys$readv(int fd, Userspace<const struct iovec*> iov
Vector<iovec, 32> vecs;
if (!vecs.try_resize(iov_count))
return ENOMEM;
if (!copy_n_from_user(vecs.data(), iov, iov_count))
return EFAULT;
TRY(copy_n_from_user(vecs.data(), iov, iov_count));
for (auto& vec : vecs) {
total_length += vec.iov_len;
if (total_length > NumericLimits<i32>::max())

View file

@ -16,8 +16,7 @@ KResultOr<FlatPtr> Process::sys$readlink(Userspace<const Syscall::SC_readlink_pa
REQUIRE_PROMISE(rpath);
Syscall::SC_readlink_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
auto path = get_syscall_path_argument(params.path);
if (path.is_error())
@ -37,8 +36,7 @@ KResultOr<FlatPtr> Process::sys$readlink(Userspace<const Syscall::SC_readlink_pa
auto& link_target = *contents.value();
auto size_to_copy = min(link_target.size(), params.buffer.size);
if (!copy_to_user(params.buffer.data, link_target.data(), size_to_copy))
return EFAULT;
TRY(copy_to_user(params.buffer.data, link_target.data(), size_to_copy));
// Note: we return the whole size here, not the copied size.
return link_target.size();
}

View file

@ -17,8 +17,7 @@ KResultOr<FlatPtr> Process::sys$realpath(Userspace<const Syscall::SC_realpath_pa
REQUIRE_PROMISE(rpath);
Syscall::SC_realpath_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
auto path = get_syscall_path_argument(params.path);
if (path.is_error())
@ -34,8 +33,7 @@ KResultOr<FlatPtr> Process::sys$realpath(Userspace<const Syscall::SC_realpath_pa
size_t ideal_size = absolute_path->length() + 1;
auto size_to_copy = min(ideal_size, params.buffer.size);
if (!copy_to_user(params.buffer.data, absolute_path->characters(), size_to_copy))
return EFAULT;
TRY(copy_to_user(params.buffer.data, absolute_path->characters(), size_to_copy));
// Note: we return the whole size here, not the copied size.
return ideal_size;
};

View file

@ -15,8 +15,7 @@ KResultOr<FlatPtr> Process::sys$rename(Userspace<const Syscall::SC_rename_params
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(cpath);
Syscall::SC_rename_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
auto old_path = get_syscall_path_argument(params.old_path);
if (old_path.is_error())
return old_path.error();

View file

@ -21,8 +21,7 @@ KResultOr<FlatPtr> Process::sys$sched_setparam(int pid, Userspace<const struct s
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(proc);
struct sched_param desired_param;
if (!copy_from_user(&desired_param, user_param))
return EFAULT;
TRY(copy_from_user(&desired_param, user_param));
if (desired_param.sched_priority < THREAD_PRIORITY_MIN || desired_param.sched_priority > THREAD_PRIORITY_MAX)
return EINVAL;
@ -68,9 +67,8 @@ KResultOr<FlatPtr> Process::sys$sched_getparam(pid_t pid, Userspace<struct sched
struct sched_param param {
priority
};
if (!copy_to_user(user_param, &param))
return EFAULT;
return 0;
return copy_to_user(user_param, &param);
}
}

View file

@ -20,8 +20,7 @@ KResultOr<FlatPtr> Process::sys$select(Userspace<const Syscall::SC_select_params
REQUIRE_PROMISE(stdio);
Syscall::SC_select_params params {};
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
if (params.nfds < 0)
return EINVAL;
@ -39,8 +38,7 @@ KResultOr<FlatPtr> Process::sys$select(Userspace<const Syscall::SC_select_params
u32 previous_signal_mask = 0;
if (params.sigmask) {
sigset_t sigmask_copy;
if (!copy_from_user(&sigmask_copy, params.sigmask))
return EFAULT;
TRY(copy_from_user(&sigmask_copy, params.sigmask));
previous_signal_mask = current_thread->update_signal_mask(sigmask_copy);
}
ScopeGuard rollback_signal_mask([&]() {
@ -54,12 +52,14 @@ KResultOr<FlatPtr> Process::sys$select(Userspace<const Syscall::SC_select_params
if (bytes_used > sizeof(fds_read))
return EINVAL;
if (params.readfds && !copy_from_user(&fds_read, params.readfds, bytes_used))
return EFAULT;
if (params.writefds && !copy_from_user(&fds_write, params.writefds, bytes_used))
return EFAULT;
if (params.exceptfds && !copy_from_user(&fds_except, params.exceptfds, bytes_used))
return EFAULT;
if (params.readfds)
TRY(copy_from_user(&fds_read, params.readfds, bytes_used));
if (params.writefds)
TRY(copy_from_user(&fds_write, params.writefds, bytes_used));
if (params.exceptfds)
TRY(copy_from_user(&fds_except, params.exceptfds, bytes_used));
Thread::SelectBlocker::FDVector fds_info;
Vector<int, FD_SETSIZE> selected_fds;
@ -119,12 +119,12 @@ KResultOr<FlatPtr> Process::sys$select(Userspace<const Syscall::SC_select_params
}
}
if (params.readfds && !copy_to_user(params.readfds, &fds_read, bytes_used))
return EFAULT;
if (params.writefds && !copy_to_user(params.writefds, &fds_write, bytes_used))
return EFAULT;
if (params.exceptfds && !copy_to_user(params.exceptfds, &fds_except, bytes_used))
return EFAULT;
if (params.readfds)
TRY(copy_to_user(params.readfds, &fds_read, bytes_used));
if (params.writefds)
TRY(copy_to_user(params.writefds, &fds_write, bytes_used));
if (params.exceptfds)
TRY(copy_to_user(params.exceptfds, &fds_except, bytes_used));
return marked_fd_count;
}
@ -133,9 +133,8 @@ KResultOr<FlatPtr> Process::sys$poll(Userspace<const Syscall::SC_poll_params*> u
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(stdio);
Syscall::SC_poll_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
Syscall::SC_poll_params params {};
TRY(copy_from_user(&params, user_params));
if (params.nfds >= fds().max_open())
return ENOBUFS;
@ -149,8 +148,8 @@ KResultOr<FlatPtr> Process::sys$poll(Userspace<const Syscall::SC_poll_params*> u
}
sigset_t sigmask = {};
if (params.sigmask && !copy_from_user(&sigmask, params.sigmask))
return EFAULT;
if (params.sigmask)
TRY(copy_from_user(&sigmask, params.sigmask));
Vector<pollfd, FD_SETSIZE> fds_copy;
if (params.nfds > 0) {
@ -160,8 +159,7 @@ KResultOr<FlatPtr> Process::sys$poll(Userspace<const Syscall::SC_poll_params*> u
return EFAULT;
if (!fds_copy.try_resize(params.nfds))
return ENOMEM;
if (!copy_from_user(fds_copy.data(), &params.fds[0], nfds_checked.value()))
return EFAULT;
TRY(copy_from_user(fds_copy.data(), &params.fds[0], nfds_checked.value()));
}
Thread::SelectBlocker::FDVector fds_info;
@ -234,8 +232,8 @@ KResultOr<FlatPtr> Process::sys$poll(Userspace<const Syscall::SC_poll_params*> u
fds_with_revents++;
}
if (params.nfds > 0 && !copy_to_user(&params.fds[0], fds_copy.data(), params.nfds * sizeof(pollfd)))
return EFAULT;
if (params.nfds > 0)
TRY(copy_to_user(&params.fds[0], fds_copy.data(), params.nfds * sizeof(pollfd)));
return fds_with_revents;
}

View file

@ -171,8 +171,7 @@ KResultOr<FlatPtr> Process::sys$setgroups(size_t count, Userspace<const gid_t*>
Vector<gid_t> new_extra_gids;
if (!new_extra_gids.try_resize(count))
return ENOMEM;
if (!copy_n_from_user(new_extra_gids.data(), user_gids, count))
return EFAULT;
TRY(copy_n_from_user(new_extra_gids.data(), user_gids, count));
HashTable<gid_t> unique_extra_gids;
for (auto& extra_gid : new_extra_gids) {

View file

@ -18,8 +18,7 @@ KResultOr<FlatPtr> Process::sys$sigprocmask(int how, Userspace<const sigset_t*>
u32 previous_signal_mask;
if (set) {
sigset_t set_value;
if (!copy_from_user(&set_value, set))
return EFAULT;
TRY(copy_from_user(&set_value, set));
switch (how) {
case SIG_BLOCK:
previous_signal_mask = current_thread->signal_mask_block(set_value, true);
@ -36,8 +35,9 @@ KResultOr<FlatPtr> Process::sys$sigprocmask(int how, Userspace<const sigset_t*>
} else {
previous_signal_mask = current_thread->signal_mask();
}
if (old_set && !copy_to_user(old_set, &previous_signal_mask))
return EFAULT;
if (old_set) {
TRY(copy_to_user(old_set, &previous_signal_mask));
}
return 0;
}
@ -46,9 +46,7 @@ KResultOr<FlatPtr> Process::sys$sigpending(Userspace<sigset_t*> set)
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(stdio);
auto pending_signals = Thread::current()->pending_signals();
if (!copy_to_user(set, &pending_signals))
return EFAULT;
return 0;
return copy_to_user(set, &pending_signals);
}
KResultOr<FlatPtr> Process::sys$sigaction(int signum, Userspace<const sigaction*> user_act, Userspace<sigaction*> user_old_act)
@ -64,13 +62,11 @@ KResultOr<FlatPtr> Process::sys$sigaction(int signum, Userspace<const sigaction*
sigaction old_act {};
old_act.sa_flags = action.flags;
old_act.sa_sigaction = reinterpret_cast<decltype(old_act.sa_sigaction)>(action.handler_or_sigaction.as_ptr());
if (!copy_to_user(user_old_act, &old_act))
return EFAULT;
TRY(copy_to_user(user_old_act, &old_act));
}
if (user_act) {
sigaction act {};
if (!copy_from_user(&act, user_act))
return EFAULT;
TRY(copy_from_user(&act, user_act));
action.flags = act.sa_flags;
action.handler_or_sigaction = VirtualAddress { reinterpret_cast<void*>(act.sa_sigaction) };
}

View file

@ -80,9 +80,8 @@ KResultOr<FlatPtr> Process::sys$accept4(Userspace<const Syscall::SC_accept4_para
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(accept);
Syscall::SC_accept4_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
Syscall::SC_accept4_params params = {};
TRY(copy_from_user(&params, user_params));
int accepting_socket_fd = params.sockfd;
Userspace<sockaddr*> user_address((FlatPtr)params.addr);
@ -90,8 +89,9 @@ KResultOr<FlatPtr> Process::sys$accept4(Userspace<const Syscall::SC_accept4_para
int flags = params.flags;
socklen_t address_size = 0;
if (user_address && !copy_from_user(&address_size, static_ptr_cast<const socklen_t*>(user_address_size)))
return EFAULT;
if (user_address) {
TRY(copy_from_user(&address_size, static_ptr_cast<const socklen_t*>(user_address_size)));
}
auto fd_allocation = TRY(m_fds.allocate());
auto accepting_socket_description = fds().file_description(accepting_socket_fd);
@ -117,10 +117,8 @@ KResultOr<FlatPtr> Process::sys$accept4(Userspace<const Syscall::SC_accept4_para
sockaddr_un address_buffer;
address_size = min(sizeof(sockaddr_un), static_cast<size_t>(address_size));
accepted_socket->get_peer_address((sockaddr*)&address_buffer, &address_size);
if (!copy_to_user(user_address, &address_buffer, address_size))
return EFAULT;
if (!copy_to_user(user_address_size, &address_size))
return EFAULT;
TRY(copy_to_user(user_address, &address_buffer, address_size));
TRY(copy_to_user(user_address_size, &address_size));
}
auto accepted_socket_description = TRY(FileDescription::try_create(*accepted_socket));
@ -175,17 +173,15 @@ KResultOr<FlatPtr> Process::sys$sendmsg(int sockfd, Userspace<const struct msghd
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(stdio);
struct msghdr msg;
if (!copy_from_user(&msg, user_msg))
return EFAULT;
struct msghdr msg = {};
TRY(copy_from_user(&msg, user_msg));
if (msg.msg_iovlen != 1)
return ENOTSUP; // FIXME: Support this :)
Vector<iovec, 1> iovs;
if (!iovs.try_resize(msg.msg_iovlen))
return ENOMEM;
if (!copy_n_from_user(iovs.data(), msg.msg_iov, msg.msg_iovlen))
return EFAULT;
TRY(copy_n_from_user(iovs.data(), msg.msg_iov, msg.msg_iovlen));
if (iovs[0].iov_len > NumericLimits<ssize_t>::max())
return EINVAL;
@ -216,16 +212,14 @@ KResultOr<FlatPtr> Process::sys$recvmsg(int sockfd, Userspace<struct msghdr*> us
REQUIRE_PROMISE(stdio);
struct msghdr msg;
if (!copy_from_user(&msg, user_msg))
return EFAULT;
TRY(copy_from_user(&msg, user_msg));
if (msg.msg_iovlen != 1)
return ENOTSUP; // FIXME: Support this :)
Vector<iovec, 1> iovs;
if (!iovs.try_resize(msg.msg_iovlen))
return ENOMEM;
if (!copy_n_from_user(iovs.data(), msg.msg_iov, msg.msg_iovlen))
return EFAULT;
TRY(copy_n_from_user(iovs.data(), msg.msg_iov, msg.msg_iovlen));
Userspace<sockaddr*> user_addr((FlatPtr)msg.msg_name);
Userspace<socklen_t*> user_addr_length(msg.msg_name ? (FlatPtr)&user_msg.unsafe_userspace_ptr()->msg_namelen : 0);
@ -272,25 +266,20 @@ KResultOr<FlatPtr> Process::sys$recvmsg(int sockfd, Userspace<struct msghdr*> us
msg_flags |= MSG_CTRUNC;
} else {
cmsg_timestamp = { { control_length, SOL_SOCKET, SCM_TIMESTAMP }, timestamp.to_timeval() };
if (!copy_to_user(msg.msg_control, &cmsg_timestamp, control_length))
return EFAULT;
TRY(copy_to_user(msg.msg_control, &cmsg_timestamp, control_length));
}
if (!copy_to_user(&user_msg.unsafe_userspace_ptr()->msg_controllen, &control_length))
return EFAULT;
TRY(copy_to_user(&user_msg.unsafe_userspace_ptr()->msg_controllen, &control_length));
}
if (!copy_to_user(&user_msg.unsafe_userspace_ptr()->msg_flags, &msg_flags))
return EFAULT;
TRY(copy_to_user(&user_msg.unsafe_userspace_ptr()->msg_flags, &msg_flags));
return result.value();
}
template<bool sockname, typename Params>
int Process::get_sock_or_peer_name(const Params& params)
KResult Process::get_sock_or_peer_name(const Params& params)
{
socklen_t addrlen_value;
if (!copy_from_user(&addrlen_value, params.addrlen, sizeof(socklen_t)))
return EFAULT;
TRY(copy_from_user(&addrlen_value, params.addrlen, sizeof(socklen_t)));
if (addrlen_value <= 0)
return EINVAL;
@ -311,37 +300,31 @@ int Process::get_sock_or_peer_name(const Params& params)
socket.get_local_address((sockaddr*)&address_buffer, &addrlen_value);
else
socket.get_peer_address((sockaddr*)&address_buffer, &addrlen_value);
if (!copy_to_user(params.addr, &address_buffer, addrlen_value))
return EFAULT;
if (!copy_to_user(params.addrlen, &addrlen_value))
return EFAULT;
return 0;
TRY(copy_to_user(params.addr, &address_buffer, addrlen_value));
return copy_to_user(params.addrlen, &addrlen_value);
}
KResultOr<FlatPtr> Process::sys$getsockname(Userspace<const Syscall::SC_getsockname_params*> user_params)
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
Syscall::SC_getsockname_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
Syscall::SC_getsockname_params params = {};
TRY(copy_from_user(&params, user_params));
return get_sock_or_peer_name<true>(params);
}
KResultOr<FlatPtr> Process::sys$getpeername(Userspace<const Syscall::SC_getpeername_params*> user_params)
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
Syscall::SC_getpeername_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
Syscall::SC_getpeername_params params = {};
TRY(copy_from_user(&params, user_params));
return get_sock_or_peer_name<false>(params);
}
KResultOr<FlatPtr> Process::sys$getsockopt(Userspace<const Syscall::SC_getsockopt_params*> user_params)
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
Syscall::SC_getsockopt_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
Syscall::SC_getsockopt_params params = {};
TRY(copy_from_user(&params, user_params));
int sockfd = params.sockfd;
int level = params.level;
@ -350,8 +333,7 @@ KResultOr<FlatPtr> Process::sys$getsockopt(Userspace<const Syscall::SC_getsockop
Userspace<socklen_t*> user_value_size((FlatPtr)params.value_size);
socklen_t value_size;
if (!copy_from_user(&value_size, params.value_size, sizeof(socklen_t)))
return EFAULT;
TRY(copy_from_user(&value_size, params.value_size, sizeof(socklen_t)));
auto description = fds().file_description(sockfd);
if (!description)
@ -368,8 +350,7 @@ KResultOr<FlatPtr> Process::sys$setsockopt(Userspace<const Syscall::SC_setsockop
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
Syscall::SC_setsockopt_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
Userspace<const void*> user_value((FlatPtr)params.value);
auto description = fds().file_description(params.sockfd);
if (!description)
@ -385,8 +366,7 @@ KResultOr<FlatPtr> Process::sys$socketpair(Userspace<const Syscall::SC_socketpai
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
Syscall::SC_socketpair_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
if (params.domain != AF_LOCAL)
return EINVAL;
@ -405,7 +385,7 @@ KResultOr<FlatPtr> Process::sys$socketpair(Userspace<const Syscall::SC_socketpai
setup_socket_fd(fds[0], pair.description0, params.type);
setup_socket_fd(fds[1], pair.description1, params.type);
if (!copy_to_user(params.sv, fds, sizeof(fds))) {
if (copy_to_user(params.sv, fds, sizeof(fds)).is_error()) {
// Avoid leaking both file descriptors on error.
m_fds[fds[0]] = {};
m_fds[fds[1]] = {};

View file

@ -19,10 +19,8 @@ KResultOr<FlatPtr> Process::sys$fstat(int fd, Userspace<stat*> user_statbuf)
if (!description)
return EBADF;
stat buffer = {};
auto result = description->stat(buffer);
if (!copy_to_user(user_statbuf, &buffer))
return EFAULT;
return result;
TRY(description->stat(buffer));
return copy_to_user(user_statbuf, &buffer);
}
KResultOr<FlatPtr> Process::sys$stat(Userspace<const Syscall::SC_stat_params*> user_params)
@ -30,8 +28,7 @@ KResultOr<FlatPtr> Process::sys$stat(Userspace<const Syscall::SC_stat_params*> u
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(rpath);
Syscall::SC_stat_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
auto path = get_syscall_path_argument(params.path);
if (path.is_error())
return path.error();
@ -55,9 +52,7 @@ KResultOr<FlatPtr> Process::sys$stat(Userspace<const Syscall::SC_stat_params*> u
auto result = metadata_or_error.value().stat(statbuf);
if (result.is_error())
return result;
if (!copy_to_user(params.statbuf, &statbuf))
return EFAULT;
return 0;
return copy_to_user(params.statbuf, &statbuf);
}
}

View file

@ -62,10 +62,7 @@ KResultOr<FlatPtr> Process::do_statvfs(String path, statvfs* buf)
}
}
if (!copy_to_user(buf, &kernelbuf))
return EFAULT;
return 0;
return copy_to_user(buf, &kernelbuf);
}
KResultOr<FlatPtr> Process::sys$statvfs(Userspace<const Syscall::SC_statvfs_params*> user_params)
@ -74,8 +71,7 @@ KResultOr<FlatPtr> Process::sys$statvfs(Userspace<const Syscall::SC_statvfs_para
REQUIRE_PROMISE(rpath);
Syscall::SC_statvfs_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
auto path = get_syscall_path_argument(params.path);
if (path.is_error())
return path.error();

View file

@ -19,8 +19,7 @@ KResultOr<FlatPtr> Process::sys$create_thread(void* (*entry)(void*), Userspace<c
REQUIRE_PROMISE(thread);
Syscall::SC_create_thread_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
unsigned detach_state = params.detach_state;
int schedule_priority = params.schedule_priority;
@ -151,9 +150,10 @@ KResultOr<FlatPtr> Process::sys$join_thread(pid_t tid, Userspace<void**> exit_va
dbgln("join_thread: retrying");
}
if (exit_value && !copy_to_user(exit_value, &joinee_exit_value))
return EFAULT;
return 0;
if (exit_value)
TRY(copy_to_user(exit_value, &joinee_exit_value));
return KSuccess;
}
KResultOr<FlatPtr> Process::sys$kill_thread(pid_t tid, int signal)
@ -212,17 +212,14 @@ KResultOr<FlatPtr> Process::sys$get_thread_name(pid_t tid, Userspace<char*> buff
if (thread_name.is_null()) {
char null_terminator = '\0';
if (!copy_to_user(buffer, &null_terminator, sizeof(null_terminator)))
return EFAULT;
return 0;
TRY(copy_to_user(buffer, &null_terminator, sizeof(null_terminator)));
return KSuccess;
}
if (thread_name.length() + 1 > buffer_size)
return ENAMETOOLONG;
if (!copy_to_user(buffer, thread_name.characters_without_null_termination(), thread_name.length() + 1))
return EFAULT;
return 0;
return copy_to_user(buffer, thread_name.characters_without_null_termination(), thread_name.length() + 1);
}
KResultOr<FlatPtr> Process::sys$gettid()

View file

@ -18,9 +18,7 @@ KResultOr<FlatPtr> Process::sys$times(Userspace<tms*> user_times)
times.tms_cutime = m_ticks_in_user_for_dead_children;
times.tms_cstime = m_ticks_in_kernel_for_dead_children;
if (!copy_to_user(user_times, &times))
return EFAULT;
TRY(copy_to_user(user_times, &times));
return TimeManagement::the().uptime_ms() & 0x7fffffff;
}

View file

@ -23,9 +23,7 @@ KResultOr<FlatPtr> Process::sys$ttyname(int fd, Userspace<char*> buffer, size_t
auto tty_name = description->tty()->tty_name();
if (size < tty_name.length() + 1)
return ERANGE;
if (!copy_to_user(buffer, tty_name.characters(), tty_name.length() + 1))
return EFAULT;
return 0;
return copy_to_user(buffer, tty_name.characters(), tty_name.length() + 1);
}
KResultOr<FlatPtr> Process::sys$ptsname(int fd, Userspace<char*> buffer, size_t size)
@ -41,9 +39,7 @@ KResultOr<FlatPtr> Process::sys$ptsname(int fd, Userspace<char*> buffer, size_t
auto pts_name = master_pty->pts_name();
if (size < pts_name.length() + 1)
return ERANGE;
if (!copy_to_user(buffer, pts_name.characters(), pts_name.length() + 1))
return EFAULT;
return 0;
return copy_to_user(buffer, pts_name.characters(), pts_name.length() + 1);
}
}

View file

@ -27,9 +27,7 @@ KResultOr<FlatPtr> Process::sys$uname(Userspace<utsname*> user_buf)
memcpy(buf.nodename, name.characters(), name.length() + 1);
});
if (!copy_to_user(user_buf, &buf))
return EFAULT;
return 0;
return copy_to_user(user_buf, &buf);
}
}

View file

@ -28,8 +28,7 @@ KResultOr<FlatPtr> Process::sys$unveil(Userspace<const Syscall::SC_unveil_params
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
Syscall::SC_unveil_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
if (!params.path.characters && !params.permissions.characters) {
m_veil_state = VeilState::Locked;

View file

@ -19,8 +19,7 @@ KResultOr<FlatPtr> Process::sys$utime(Userspace<const char*> user_path, size_t p
return path.error();
utimbuf buf;
if (user_buf) {
if (!copy_from_user(&buf, user_buf))
return EFAULT;
TRY(copy_from_user(&buf, user_buf));
} else {
auto now = kgettimeofday().to_truncated_seconds();
// Not a bug!

View file

@ -25,8 +25,7 @@ KResultOr<FlatPtr> Process::sys$waitid(Userspace<const Syscall::SC_waitid_params
REQUIRE_PROMISE(proc);
Syscall::SC_waitid_params params;
if (!copy_from_user(&params, user_params))
return EFAULT;
TRY(copy_from_user(&params, user_params));
Variant<Empty, NonnullRefPtr<Process>, NonnullRefPtr<ProcessGroup>> waitee = Empty {};
switch (params.idtype) {
@ -59,9 +58,7 @@ KResultOr<FlatPtr> Process::sys$waitid(Userspace<const Syscall::SC_waitid_params
if (siginfo_or_error.is_error())
return siginfo_or_error.error();
if (!copy_to_user(params.infop, &siginfo_or_error.value()))
return EFAULT;
return 0;
return copy_to_user(params.infop, &siginfo_or_error.value());
}
}

View file

@ -26,8 +26,7 @@ KResultOr<FlatPtr> Process::sys$writev(int fd, Userspace<const struct iovec*> io
Vector<iovec, 32> vecs;
if (!vecs.try_resize(iov_count))
return ENOMEM;
if (!copy_n_from_user(vecs.data(), iov, iov_count))
return EFAULT;
TRY(copy_n_from_user(vecs.data(), iov, iov_count));
for (auto& vec : vecs) {
total_length += vec.iov_len;
if (total_length > NumericLimits<i32>::max())