mirror of
https://github.com/SerenityOS/serenity
synced 2024-09-06 17:06:31 +00:00
Kernel: Use copy_typed_from_user() in more places :^)
This commit is contained in:
parent
39d9337db5
commit
abf2204402
|
@ -318,8 +318,7 @@ ErrorOr<void> Inode::can_apply_flock(OpenFileDescription const& description, flo
|
|||
|
||||
ErrorOr<void> Inode::apply_flock(Process const& process, OpenFileDescription const& description, Userspace<flock const*> input_lock)
|
||||
{
|
||||
flock new_lock = {};
|
||||
TRY(copy_from_user(&new_lock, input_lock));
|
||||
auto new_lock = TRY(copy_typed_from_user(input_lock));
|
||||
TRY(normalize_flock(description, new_lock));
|
||||
|
||||
MutexLocker locker(m_inode_lock);
|
||||
|
|
|
@ -61,9 +61,8 @@ ErrorOr<void> GenericFramebufferDevice::ioctl(OpenFileDescription&, unsigned req
|
|||
return copy_to_user(user_head_properties, &head_properties);
|
||||
}
|
||||
case FB_IOCTL_SET_HEAD_RESOLUTION: {
|
||||
auto user_head_resolution = static_ptr_cast<FBHeadResolution*>(arg);
|
||||
FBHeadResolution head_resolution;
|
||||
TRY(copy_from_user(&head_resolution, user_head_resolution));
|
||||
auto user_head_resolution = static_ptr_cast<FBHeadResolution const*>(arg);
|
||||
auto head_resolution = TRY(copy_typed_from_user(user_head_resolution));
|
||||
TRY(verify_head_index(head_resolution.head_index));
|
||||
|
||||
if (head_resolution.pitch < 0)
|
||||
|
@ -76,9 +75,8 @@ ErrorOr<void> GenericFramebufferDevice::ioctl(OpenFileDescription&, unsigned req
|
|||
return {};
|
||||
}
|
||||
case FB_IOCTL_SET_HEAD_VERTICAL_OFFSET_BUFFER: {
|
||||
auto user_head_vertical_buffer_offset = static_ptr_cast<FBHeadVerticalOffset*>(arg);
|
||||
FBHeadVerticalOffset head_vertical_buffer_offset;
|
||||
TRY(copy_from_user(&head_vertical_buffer_offset, user_head_vertical_buffer_offset));
|
||||
auto user_head_vertical_buffer_offset = static_ptr_cast<FBHeadVerticalOffset const*>(arg);
|
||||
auto head_vertical_buffer_offset = TRY(copy_typed_from_user(user_head_vertical_buffer_offset));
|
||||
TRY(verify_head_index(head_vertical_buffer_offset.head_index));
|
||||
|
||||
if (head_vertical_buffer_offset.offsetted < 0 || head_vertical_buffer_offset.offsetted > 1)
|
||||
|
@ -98,9 +96,8 @@ ErrorOr<void> GenericFramebufferDevice::ioctl(OpenFileDescription&, unsigned req
|
|||
case FB_IOCTL_FLUSH_HEAD_BUFFERS: {
|
||||
if (!partial_flushing_support())
|
||||
return Error::from_errno(ENOTSUP);
|
||||
auto user_flush_rects = static_ptr_cast<FBFlushRects*>(arg);
|
||||
FBFlushRects flush_rects;
|
||||
TRY(copy_from_user(&flush_rects, user_flush_rects));
|
||||
auto user_flush_rects = static_ptr_cast<FBFlushRects const*>(arg);
|
||||
auto flush_rects = TRY(copy_typed_from_user(user_flush_rects));
|
||||
if (Checked<unsigned>::multiplication_would_overflow(flush_rects.count, sizeof(FBRect)))
|
||||
return Error::from_errno(EFAULT);
|
||||
MutexLocker locker(m_flushing_lock);
|
||||
|
@ -117,11 +114,9 @@ ErrorOr<void> GenericFramebufferDevice::ioctl(OpenFileDescription&, unsigned req
|
|||
if (!flushing_support())
|
||||
return Error::from_errno(ENOTSUP);
|
||||
// Note: We accept a FBRect, but we only really care about the head_index value.
|
||||
auto user_rect = static_ptr_cast<FBRect*>(arg);
|
||||
FBRect rect;
|
||||
TRY(copy_from_user(&rect, user_rect));
|
||||
auto user_rect = static_ptr_cast<FBRect const*>(arg);
|
||||
auto rect = TRY(copy_typed_from_user(user_rect));
|
||||
TRY(verify_head_index(rect.head_index));
|
||||
|
||||
TRY(flush_head_buffer(rect.head_index));
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -112,23 +112,17 @@ ErrorOr<void> Socket::setsockopt(int level, int option, Userspace<const void*> u
|
|||
case SO_TIMESTAMP:
|
||||
if (user_value_size != sizeof(int))
|
||||
return EINVAL;
|
||||
{
|
||||
int timestamp;
|
||||
TRY(copy_from_user(×tamp, static_ptr_cast<const int*>(user_value)));
|
||||
m_timestamp = timestamp;
|
||||
}
|
||||
if (m_timestamp && (domain() != AF_INET || type() == SOCK_STREAM)) {
|
||||
m_timestamp = TRY(copy_typed_from_user(static_ptr_cast<int const*>(user_value)));
|
||||
if (m_timestamp != 0 && (domain() != AF_INET || type() == SOCK_STREAM)) {
|
||||
// FIXME: Support SO_TIMESTAMP for more protocols?
|
||||
m_timestamp = 0;
|
||||
return ENOTSUP;
|
||||
}
|
||||
return {};
|
||||
case SO_DONTROUTE: {
|
||||
int routing_disabled;
|
||||
if (user_value_size != sizeof(routing_disabled))
|
||||
if (user_value_size != sizeof(int))
|
||||
return EINVAL;
|
||||
TRY(copy_from_user(&routing_disabled, static_ptr_cast<const int*>(user_value)));
|
||||
m_routing_disabled = routing_disabled != 0;
|
||||
m_routing_disabled = TRY(copy_typed_from_user(static_ptr_cast<int const*>(user_value))) != 0;
|
||||
return {};
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 :)
|
||||
|
|
|
@ -476,9 +476,6 @@ ErrorOr<void> TTY::ioctl(OpenFileDescription&, unsigned request, Userspace<void*
|
|||
{
|
||||
REQUIRE_PROMISE(tty);
|
||||
auto& current_process = Process::current();
|
||||
Userspace<termios*> user_termios;
|
||||
Userspace<winsize*> user_winsize;
|
||||
|
||||
#if 0
|
||||
// FIXME: When should we block things?
|
||||
// How do we make this work together with MasterPTY forwarding to us?
|
||||
|
@ -521,15 +518,14 @@ ErrorOr<void> TTY::ioctl(OpenFileDescription&, unsigned request, Userspace<void*
|
|||
return {};
|
||||
}
|
||||
case TCGETS: {
|
||||
user_termios = static_ptr_cast<termios*>(arg);
|
||||
auto user_termios = static_ptr_cast<termios*>(arg);
|
||||
return copy_to_user(user_termios, &m_termios);
|
||||
}
|
||||
case TCSETS:
|
||||
case TCSETSF:
|
||||
case TCSETSW: {
|
||||
user_termios = static_ptr_cast<termios*>(arg);
|
||||
termios termios;
|
||||
TRY(copy_from_user(&termios, user_termios));
|
||||
auto user_termios = static_ptr_cast<termios const*>(arg);
|
||||
auto termios = TRY(copy_typed_from_user(user_termios));
|
||||
auto rc = set_termios(termios);
|
||||
if (request == TCSETSF)
|
||||
flush_input();
|
||||
|
@ -545,18 +541,18 @@ ErrorOr<void> TTY::ioctl(OpenFileDescription&, unsigned request, Userspace<void*
|
|||
}
|
||||
return {};
|
||||
}
|
||||
case TIOCGWINSZ:
|
||||
user_winsize = static_ptr_cast<winsize*>(arg);
|
||||
case TIOCGWINSZ: {
|
||||
auto user_winsize = static_ptr_cast<winsize*>(arg);
|
||||
winsize ws;
|
||||
ws.ws_row = m_rows;
|
||||
ws.ws_col = m_columns;
|
||||
ws.ws_xpixel = 0;
|
||||
ws.ws_ypixel = 0;
|
||||
return copy_to_user(user_winsize, &ws);
|
||||
}
|
||||
case TIOCSWINSZ: {
|
||||
user_winsize = static_ptr_cast<winsize*>(arg);
|
||||
winsize ws;
|
||||
TRY(copy_from_user(&ws, user_winsize));
|
||||
auto user_winsize = static_ptr_cast<winsize const*>(arg);
|
||||
auto ws = TRY(copy_typed_from_user(user_winsize));
|
||||
if (ws.ws_col == m_columns && ws.ws_row == m_rows)
|
||||
return {};
|
||||
m_rows = ws.ws_row;
|
||||
|
|
Loading…
Reference in a new issue