mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 15:48:12 +00:00
Kernel: Use copy_typed_from_user() in more places :^)
This commit is contained in:
parent
39d9337db5
commit
abf2204402
9 changed files with 41 additions and 66 deletions
|
@ -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)
|
ErrorOr<void> Inode::apply_flock(Process const& process, OpenFileDescription const& description, Userspace<flock const*> input_lock)
|
||||||
{
|
{
|
||||||
flock new_lock = {};
|
auto new_lock = TRY(copy_typed_from_user(input_lock));
|
||||||
TRY(copy_from_user(&new_lock, input_lock));
|
|
||||||
TRY(normalize_flock(description, new_lock));
|
TRY(normalize_flock(description, new_lock));
|
||||||
|
|
||||||
MutexLocker locker(m_inode_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);
|
return copy_to_user(user_head_properties, &head_properties);
|
||||||
}
|
}
|
||||||
case FB_IOCTL_SET_HEAD_RESOLUTION: {
|
case FB_IOCTL_SET_HEAD_RESOLUTION: {
|
||||||
auto user_head_resolution = static_ptr_cast<FBHeadResolution*>(arg);
|
auto user_head_resolution = static_ptr_cast<FBHeadResolution const*>(arg);
|
||||||
FBHeadResolution head_resolution;
|
auto head_resolution = TRY(copy_typed_from_user(user_head_resolution));
|
||||||
TRY(copy_from_user(&head_resolution, user_head_resolution));
|
|
||||||
TRY(verify_head_index(head_resolution.head_index));
|
TRY(verify_head_index(head_resolution.head_index));
|
||||||
|
|
||||||
if (head_resolution.pitch < 0)
|
if (head_resolution.pitch < 0)
|
||||||
|
@ -76,9 +75,8 @@ ErrorOr<void> GenericFramebufferDevice::ioctl(OpenFileDescription&, unsigned req
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
case FB_IOCTL_SET_HEAD_VERTICAL_OFFSET_BUFFER: {
|
case FB_IOCTL_SET_HEAD_VERTICAL_OFFSET_BUFFER: {
|
||||||
auto user_head_vertical_buffer_offset = static_ptr_cast<FBHeadVerticalOffset*>(arg);
|
auto user_head_vertical_buffer_offset = static_ptr_cast<FBHeadVerticalOffset const*>(arg);
|
||||||
FBHeadVerticalOffset head_vertical_buffer_offset;
|
auto head_vertical_buffer_offset = TRY(copy_typed_from_user(user_head_vertical_buffer_offset));
|
||||||
TRY(copy_from_user(&head_vertical_buffer_offset, user_head_vertical_buffer_offset));
|
|
||||||
TRY(verify_head_index(head_vertical_buffer_offset.head_index));
|
TRY(verify_head_index(head_vertical_buffer_offset.head_index));
|
||||||
|
|
||||||
if (head_vertical_buffer_offset.offsetted < 0 || head_vertical_buffer_offset.offsetted > 1)
|
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: {
|
case FB_IOCTL_FLUSH_HEAD_BUFFERS: {
|
||||||
if (!partial_flushing_support())
|
if (!partial_flushing_support())
|
||||||
return Error::from_errno(ENOTSUP);
|
return Error::from_errno(ENOTSUP);
|
||||||
auto user_flush_rects = static_ptr_cast<FBFlushRects*>(arg);
|
auto user_flush_rects = static_ptr_cast<FBFlushRects const*>(arg);
|
||||||
FBFlushRects flush_rects;
|
auto flush_rects = TRY(copy_typed_from_user(user_flush_rects));
|
||||||
TRY(copy_from_user(&flush_rects, user_flush_rects));
|
|
||||||
if (Checked<unsigned>::multiplication_would_overflow(flush_rects.count, sizeof(FBRect)))
|
if (Checked<unsigned>::multiplication_would_overflow(flush_rects.count, sizeof(FBRect)))
|
||||||
return Error::from_errno(EFAULT);
|
return Error::from_errno(EFAULT);
|
||||||
MutexLocker locker(m_flushing_lock);
|
MutexLocker locker(m_flushing_lock);
|
||||||
|
@ -117,11 +114,9 @@ ErrorOr<void> GenericFramebufferDevice::ioctl(OpenFileDescription&, unsigned req
|
||||||
if (!flushing_support())
|
if (!flushing_support())
|
||||||
return Error::from_errno(ENOTSUP);
|
return Error::from_errno(ENOTSUP);
|
||||||
// Note: We accept a FBRect, but we only really care about the head_index value.
|
// Note: We accept a FBRect, but we only really care about the head_index value.
|
||||||
auto user_rect = static_ptr_cast<FBRect*>(arg);
|
auto user_rect = static_ptr_cast<FBRect const*>(arg);
|
||||||
FBRect rect;
|
auto rect = TRY(copy_typed_from_user(user_rect));
|
||||||
TRY(copy_from_user(&rect, user_rect));
|
|
||||||
TRY(verify_head_index(rect.head_index));
|
TRY(verify_head_index(rect.head_index));
|
||||||
|
|
||||||
TRY(flush_head_buffer(rect.head_index));
|
TRY(flush_head_buffer(rect.head_index));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,23 +112,17 @@ ErrorOr<void> Socket::setsockopt(int level, int option, Userspace<const void*> u
|
||||||
case SO_TIMESTAMP:
|
case SO_TIMESTAMP:
|
||||||
if (user_value_size != sizeof(int))
|
if (user_value_size != sizeof(int))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
{
|
m_timestamp = TRY(copy_typed_from_user(static_ptr_cast<int const*>(user_value)));
|
||||||
int timestamp;
|
if (m_timestamp != 0 && (domain() != AF_INET || type() == SOCK_STREAM)) {
|
||||||
TRY(copy_from_user(×tamp, static_ptr_cast<const int*>(user_value)));
|
|
||||||
m_timestamp = timestamp;
|
|
||||||
}
|
|
||||||
if (m_timestamp && (domain() != AF_INET || type() == SOCK_STREAM)) {
|
|
||||||
// FIXME: Support SO_TIMESTAMP for more protocols?
|
// FIXME: Support SO_TIMESTAMP for more protocols?
|
||||||
m_timestamp = 0;
|
m_timestamp = 0;
|
||||||
return ENOTSUP;
|
return ENOTSUP;
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
case SO_DONTROUTE: {
|
case SO_DONTROUTE: {
|
||||||
int routing_disabled;
|
if (user_value_size != sizeof(int))
|
||||||
if (user_value_size != sizeof(routing_disabled))
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
TRY(copy_from_user(&routing_disabled, static_ptr_cast<const int*>(user_value)));
|
m_routing_disabled = TRY(copy_typed_from_user(static_ptr_cast<int const*>(user_value))) != 0;
|
||||||
m_routing_disabled = routing_disabled != 0;
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -16,9 +16,7 @@ ErrorOr<FlatPtr> Process::sys$ioctl(int fd, unsigned request, FlatPtr arg)
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
auto description = TRY(fds().open_file_description(fd));
|
auto description = TRY(fds().open_file_description(fd));
|
||||||
if (request == FIONBIO) {
|
if (request == FIONBIO) {
|
||||||
int non_blocking;
|
description->set_blocking(TRY(copy_typed_from_user(Userspace<int const*>(arg))) == 0);
|
||||||
TRY(copy_from_user(&non_blocking, Userspace<const int*>(arg)));
|
|
||||||
description->set_blocking(non_blocking == 0);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
TRY(description->file().ioctl(*description, request, arg));
|
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
|
// This function can be called from the context of another
|
||||||
// process that called PT_PEEK
|
// process that called PT_PEEK
|
||||||
ScopedAddressSpaceSwitcher switcher(*this);
|
ScopedAddressSpaceSwitcher switcher(*this);
|
||||||
FlatPtr data;
|
return TRY(copy_typed_from_user(address));
|
||||||
TRY(copy_from_user(&data, address));
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> Process::peek_user_data(Span<u8> destination, Userspace<const u8*> 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)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
REQUIRE_PROMISE(proc);
|
REQUIRE_PROMISE(proc);
|
||||||
struct sched_param desired_param;
|
auto param = TRY(copy_typed_from_user(user_param));
|
||||||
TRY(copy_from_user(&desired_param, 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;
|
return EINVAL;
|
||||||
|
|
||||||
auto* peer = Thread::current();
|
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())
|
if (!is_superuser() && euid() != peer->process().uid() && uid() != peer->process().uid())
|
||||||
return EPERM;
|
return EPERM;
|
||||||
|
|
||||||
peer->set_priority((u32)desired_param.sched_priority);
|
peer->set_priority((u32)param.sched_priority);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,7 @@ ErrorOr<FlatPtr> Process::sys$sigprocmask(int how, Userspace<const sigset_t*> se
|
||||||
auto current_thread = Thread::current();
|
auto current_thread = Thread::current();
|
||||||
u32 previous_signal_mask;
|
u32 previous_signal_mask;
|
||||||
if (set) {
|
if (set) {
|
||||||
sigset_t set_value;
|
auto set_value = TRY(copy_typed_from_user(set));
|
||||||
TRY(copy_from_user(&set_value, set));
|
|
||||||
switch (how) {
|
switch (how) {
|
||||||
case SIG_BLOCK:
|
case SIG_BLOCK:
|
||||||
previous_signal_mask = current_thread->signal_mask_block(set_value, true);
|
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));
|
TRY(copy_to_user(user_old_act, &old_act));
|
||||||
}
|
}
|
||||||
if (user_act) {
|
if (user_act) {
|
||||||
sigaction act {};
|
auto act = TRY(copy_typed_from_user(user_act));
|
||||||
TRY(copy_from_user(&act, user_act));
|
|
||||||
action.flags = act.sa_flags;
|
action.flags = act.sa_flags;
|
||||||
action.handler_or_sigaction = VirtualAddress { reinterpret_cast<void*>(act.sa_sigaction) };
|
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;
|
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)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
REQUIRE_PROMISE(sigaction);
|
REQUIRE_PROMISE(sigaction);
|
||||||
|
|
||||||
if (old_ss) {
|
if (user_old_ss) {
|
||||||
stack_t old_ss_value;
|
stack_t old_ss_value;
|
||||||
old_ss_value.ss_sp = (void*)Thread::current()->m_alternative_signal_stack;
|
old_ss_value.ss_sp = (void*)Thread::current()->m_alternative_signal_stack;
|
||||||
old_ss_value.ss_size = Thread::current()->m_alternative_signal_stack_size;
|
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;
|
old_ss_value.ss_flags = SS_DISABLE;
|
||||||
else if (Thread::current()->is_in_alternative_signal_stack())
|
else if (Thread::current()->is_in_alternative_signal_stack())
|
||||||
old_ss_value.ss_flags = SS_ONSTACK;
|
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) {
|
if (user_ss) {
|
||||||
stack_t ss_value;
|
auto ss = TRY(copy_typed_from_user(user_ss));
|
||||||
TRY(copy_from_user(&ss_value, ss));
|
|
||||||
|
|
||||||
if (Thread::current()->is_in_alternative_signal_stack())
|
if (Thread::current()->is_in_alternative_signal_stack())
|
||||||
return EPERM;
|
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_size = 0;
|
||||||
Thread::current()->m_alternative_signal_stack = 0;
|
Thread::current()->m_alternative_signal_stack = 0;
|
||||||
} else if (ss_value.ss_flags == 0) {
|
} else if (ss.ss_flags == 0) {
|
||||||
if (ss_value.ss_size <= MINSIGSTKSZ)
|
if (ss.ss_size <= MINSIGSTKSZ)
|
||||||
return ENOMEM;
|
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;
|
return ENOMEM;
|
||||||
|
|
||||||
// In order to preserve compatibility with our MAP_STACK, W^X and syscall region
|
// 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
|
// protections, sigaltstack ranges are carved out of their regions, zeroed, and
|
||||||
// turned into read/writable MAP_STACK-enabled regions.
|
// turned into read/writable MAP_STACK-enabled regions.
|
||||||
// This is inspired by OpenBSD's solution: https://man.openbsd.org/sigaltstack.2
|
// 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 = (FlatPtr)ss.ss_sp;
|
||||||
Thread::current()->m_alternative_signal_stack_size = ss_value.ss_size;
|
Thread::current()->m_alternative_signal_stack_size = ss.ss_size;
|
||||||
} else {
|
} else {
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,8 +162,7 @@ ErrorOr<FlatPtr> Process::sys$sendmsg(int sockfd, Userspace<const struct msghdr*
|
||||||
{
|
{
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||||
REQUIRE_PROMISE(stdio);
|
REQUIRE_PROMISE(stdio);
|
||||||
struct msghdr msg = {};
|
auto msg = TRY(copy_typed_from_user(user_msg));
|
||||||
TRY(copy_from_user(&msg, user_msg));
|
|
||||||
|
|
||||||
if (msg.msg_iovlen != 1)
|
if (msg.msg_iovlen != 1)
|
||||||
return ENOTSUP; // FIXME: Support this :)
|
return ENOTSUP; // FIXME: Support this :)
|
||||||
|
|
|
@ -476,9 +476,6 @@ ErrorOr<void> TTY::ioctl(OpenFileDescription&, unsigned request, Userspace<void*
|
||||||
{
|
{
|
||||||
REQUIRE_PROMISE(tty);
|
REQUIRE_PROMISE(tty);
|
||||||
auto& current_process = Process::current();
|
auto& current_process = Process::current();
|
||||||
Userspace<termios*> user_termios;
|
|
||||||
Userspace<winsize*> user_winsize;
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// FIXME: When should we block things?
|
// FIXME: When should we block things?
|
||||||
// How do we make this work together with MasterPTY forwarding to us?
|
// 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 {};
|
return {};
|
||||||
}
|
}
|
||||||
case TCGETS: {
|
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);
|
return copy_to_user(user_termios, &m_termios);
|
||||||
}
|
}
|
||||||
case TCSETS:
|
case TCSETS:
|
||||||
case TCSETSF:
|
case TCSETSF:
|
||||||
case TCSETSW: {
|
case TCSETSW: {
|
||||||
user_termios = static_ptr_cast<termios*>(arg);
|
auto user_termios = static_ptr_cast<termios const*>(arg);
|
||||||
termios termios;
|
auto termios = TRY(copy_typed_from_user(user_termios));
|
||||||
TRY(copy_from_user(&termios, user_termios));
|
|
||||||
auto rc = set_termios(termios);
|
auto rc = set_termios(termios);
|
||||||
if (request == TCSETSF)
|
if (request == TCSETSF)
|
||||||
flush_input();
|
flush_input();
|
||||||
|
@ -545,18 +541,18 @@ ErrorOr<void> TTY::ioctl(OpenFileDescription&, unsigned request, Userspace<void*
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
case TIOCGWINSZ:
|
case TIOCGWINSZ: {
|
||||||
user_winsize = static_ptr_cast<winsize*>(arg);
|
auto user_winsize = static_ptr_cast<winsize*>(arg);
|
||||||
winsize ws;
|
winsize ws;
|
||||||
ws.ws_row = m_rows;
|
ws.ws_row = m_rows;
|
||||||
ws.ws_col = m_columns;
|
ws.ws_col = m_columns;
|
||||||
ws.ws_xpixel = 0;
|
ws.ws_xpixel = 0;
|
||||||
ws.ws_ypixel = 0;
|
ws.ws_ypixel = 0;
|
||||||
return copy_to_user(user_winsize, &ws);
|
return copy_to_user(user_winsize, &ws);
|
||||||
|
}
|
||||||
case TIOCSWINSZ: {
|
case TIOCSWINSZ: {
|
||||||
user_winsize = static_ptr_cast<winsize*>(arg);
|
auto user_winsize = static_ptr_cast<winsize const*>(arg);
|
||||||
winsize ws;
|
auto ws = TRY(copy_typed_from_user(user_winsize));
|
||||||
TRY(copy_from_user(&ws, user_winsize));
|
|
||||||
if (ws.ws_col == m_columns && ws.ws_row == m_rows)
|
if (ws.ws_col == m_columns && ws.ws_row == m_rows)
|
||||||
return {};
|
return {};
|
||||||
m_rows = ws.ws_row;
|
m_rows = ws.ws_row;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue