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:
parent
9903f5c6ef
commit
48a0b31c47
57 changed files with 318 additions and 551 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
auto path = TRY(get_syscall_path_argument(params.path));
|
||||
return VirtualFileSystem::the().chown(path->view(), params.uid, params.gid, current_directory());
|
||||
}
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, 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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, 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]);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
Thread::BlockTimeout timeout;
|
||||
u32 cmd = params.futex_op & FUTEX_CMD_MASK;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
auto description = fds().file_description(params.fd);
|
||||
if (!description)
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, 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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
Syscall::SC_getkeymap_params params {};
|
||||
TRY(copy_from_user(¶ms, 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, 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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, 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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, 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));
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, 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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, 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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
auto old_range = TRY(expand_range_to_page_boundaries((FlatPtr)params.old_address, params.old_size));
|
||||
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
auto source_fd = params.source_fd;
|
||||
auto target_or_error = try_copy_kstring_from_user(params.target);
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
int dirfd = params.dirfd;
|
||||
int options = params.options;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
if (params.promises.length > 1024 || params.execpromises.length > 1024)
|
||||
return E2BIG;
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
if (params.key.length == 0 || params.key.length > 16 * KiB)
|
||||
return EINVAL;
|
||||
if (params.value.length > 16 * KiB)
|
||||
|
|
|
@ -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(®s, (const PtraceRegisters*)params.addr))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(®s, (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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, 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)
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, 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();
|
||||
}
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, 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;
|
||||
};
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
auto old_path = get_syscall_path_argument(params.old_path);
|
||||
if (old_path.is_error())
|
||||
return old_path.error();
|
||||
|
|
|
@ -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, ¶m))
|
||||
return EFAULT;
|
||||
return 0;
|
||||
|
||||
return copy_to_user(user_param, ¶m);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, 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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
Syscall::SC_poll_params params {};
|
||||
TRY(copy_from_user(¶ms, 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(), ¶ms.fds[0], nfds_checked.value()))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(fds_copy.data(), ¶ms.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(¶ms.fds[0], fds_copy.data(), params.nfds * sizeof(pollfd)))
|
||||
return EFAULT;
|
||||
if (params.nfds > 0)
|
||||
TRY(copy_to_user(¶ms.fds[0], fds_copy.data(), params.nfds * sizeof(pollfd)));
|
||||
|
||||
return fds_with_revents;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) };
|
||||
}
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
Syscall::SC_accept4_params params = {};
|
||||
TRY(copy_from_user(¶ms, 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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
Syscall::SC_getsockname_params params = {};
|
||||
TRY(copy_from_user(¶ms, 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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
Syscall::SC_getpeername_params params = {};
|
||||
TRY(copy_from_user(¶ms, 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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
Syscall::SC_getsockopt_params params = {};
|
||||
TRY(copy_from_user(¶ms, 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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, 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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, 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]] = {};
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
auto path = get_syscall_path_argument(params.path);
|
||||
if (path.is_error())
|
||||
return path.error();
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, 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()
|
||||
|
|
|
@ -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, ×))
|
||||
return EFAULT;
|
||||
|
||||
TRY(copy_to_user(user_times, ×));
|
||||
return TimeManagement::the().uptime_ms() & 0x7fffffff;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
if (!params.path.characters && !params.permissions.characters) {
|
||||
m_veil_state = VeilState::Locked;
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, 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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue