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

Kernel: Use copy_typed_from_user() in more places :^)

This commit is contained in:
Andreas Kling 2021-12-17 09:12:20 +01:00
parent 39d9337db5
commit abf2204402
9 changed files with 41 additions and 66 deletions

View file

@ -16,9 +16,7 @@ ErrorOr<FlatPtr> Process::sys$ioctl(int fd, unsigned request, FlatPtr arg)
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
auto description = TRY(fds().open_file_description(fd));
if (request == FIONBIO) {
int non_blocking;
TRY(copy_from_user(&non_blocking, Userspace<const int*>(arg)));
description->set_blocking(non_blocking == 0);
description->set_blocking(TRY(copy_typed_from_user(Userspace<int const*>(arg))) == 0);
return 0;
}
TRY(description->file().ioctl(*description, request, arg));

View file

@ -180,9 +180,7 @@ ErrorOr<FlatPtr> Process::peek_user_data(Userspace<const FlatPtr*> address)
// This function can be called from the context of another
// process that called PT_PEEK
ScopedAddressSpaceSwitcher switcher(*this);
FlatPtr data;
TRY(copy_from_user(&data, address));
return data;
return TRY(copy_typed_from_user(address));
}
ErrorOr<void> Process::peek_user_data(Span<u8> destination, Userspace<const u8*> address)

View file

@ -20,10 +20,9 @@ ErrorOr<FlatPtr> Process::sys$sched_setparam(int pid, Userspace<const struct sch
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(proc);
struct sched_param desired_param;
TRY(copy_from_user(&desired_param, user_param));
auto param = TRY(copy_typed_from_user(user_param));
if (desired_param.sched_priority < THREAD_PRIORITY_MIN || desired_param.sched_priority > THREAD_PRIORITY_MAX)
if (param.sched_priority < THREAD_PRIORITY_MIN || param.sched_priority > THREAD_PRIORITY_MAX)
return EINVAL;
auto* peer = Thread::current();
@ -37,7 +36,7 @@ ErrorOr<FlatPtr> Process::sys$sched_setparam(int pid, Userspace<const struct sch
if (!is_superuser() && euid() != peer->process().uid() && uid() != peer->process().uid())
return EPERM;
peer->set_priority((u32)desired_param.sched_priority);
peer->set_priority((u32)param.sched_priority);
return 0;
}

View file

@ -18,8 +18,7 @@ ErrorOr<FlatPtr> Process::sys$sigprocmask(int how, Userspace<const sigset_t*> se
auto current_thread = Thread::current();
u32 previous_signal_mask;
if (set) {
sigset_t set_value;
TRY(copy_from_user(&set_value, set));
auto set_value = TRY(copy_typed_from_user(set));
switch (how) {
case SIG_BLOCK:
previous_signal_mask = current_thread->signal_mask_block(set_value, true);
@ -67,8 +66,7 @@ ErrorOr<FlatPtr> Process::sys$sigaction(int signum, Userspace<const sigaction*>
TRY(copy_to_user(user_old_act, &old_act));
}
if (user_act) {
sigaction act {};
TRY(copy_from_user(&act, user_act));
auto act = TRY(copy_typed_from_user(user_act));
action.flags = act.sa_flags;
action.handler_or_sigaction = VirtualAddress { reinterpret_cast<void*>(act.sa_sigaction) };
}
@ -258,12 +256,12 @@ ErrorOr<void> Process::remap_range_as_stack(FlatPtr address, size_t size)
return EINVAL;
}
ErrorOr<FlatPtr> Process::sys$sigaltstack(Userspace<const stack_t*> ss, Userspace<stack_t*> old_ss)
ErrorOr<FlatPtr> Process::sys$sigaltstack(Userspace<const stack_t*> user_ss, Userspace<stack_t*> user_old_ss)
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(sigaction);
if (old_ss) {
if (user_old_ss) {
stack_t old_ss_value;
old_ss_value.ss_sp = (void*)Thread::current()->m_alternative_signal_stack;
old_ss_value.ss_size = Thread::current()->m_alternative_signal_stack_size;
@ -272,33 +270,32 @@ ErrorOr<FlatPtr> Process::sys$sigaltstack(Userspace<const stack_t*> ss, Userspac
old_ss_value.ss_flags = SS_DISABLE;
else if (Thread::current()->is_in_alternative_signal_stack())
old_ss_value.ss_flags = SS_ONSTACK;
TRY(copy_to_user(old_ss, &old_ss_value));
TRY(copy_to_user(user_old_ss, &old_ss_value));
}
if (ss) {
stack_t ss_value;
TRY(copy_from_user(&ss_value, ss));
if (user_ss) {
auto ss = TRY(copy_typed_from_user(user_ss));
if (Thread::current()->is_in_alternative_signal_stack())
return EPERM;
if (ss_value.ss_flags == SS_DISABLE) {
if (ss.ss_flags == SS_DISABLE) {
Thread::current()->m_alternative_signal_stack_size = 0;
Thread::current()->m_alternative_signal_stack = 0;
} else if (ss_value.ss_flags == 0) {
if (ss_value.ss_size <= MINSIGSTKSZ)
} else if (ss.ss_flags == 0) {
if (ss.ss_size <= MINSIGSTKSZ)
return ENOMEM;
if (Checked<FlatPtr>::addition_would_overflow((FlatPtr)ss_value.ss_sp, ss_value.ss_size))
if (Checked<FlatPtr>::addition_would_overflow((FlatPtr)ss.ss_sp, ss.ss_size))
return ENOMEM;
// In order to preserve compatibility with our MAP_STACK, W^X and syscall region
// protections, sigaltstack ranges are carved out of their regions, zeroed, and
// turned into read/writable MAP_STACK-enabled regions.
// This is inspired by OpenBSD's solution: https://man.openbsd.org/sigaltstack.2
TRY(remap_range_as_stack((FlatPtr)ss_value.ss_sp, ss_value.ss_size));
TRY(remap_range_as_stack((FlatPtr)ss.ss_sp, ss.ss_size));
Thread::current()->m_alternative_signal_stack = (FlatPtr)ss_value.ss_sp;
Thread::current()->m_alternative_signal_stack_size = ss_value.ss_size;
Thread::current()->m_alternative_signal_stack = (FlatPtr)ss.ss_sp;
Thread::current()->m_alternative_signal_stack_size = ss.ss_size;
} else {
return EINVAL;
}

View file

@ -162,8 +162,7 @@ ErrorOr<FlatPtr> Process::sys$sendmsg(int sockfd, Userspace<const struct msghdr*
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(stdio);
struct msghdr msg = {};
TRY(copy_from_user(&msg, user_msg));
auto msg = TRY(copy_typed_from_user(user_msg));
if (msg.msg_iovlen != 1)
return ENOTSUP; // FIXME: Support this :)