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
Notes: sideshowbarker 2024-07-18 04:41:52 +09:00
57 changed files with 318 additions and 551 deletions

View File

@ -476,10 +476,10 @@ Vector<FlatPtr> Processor::capture_stack_trace(Thread& thread, size_t max_frames
break;
if (Memory::is_user_range(VirtualAddress(stack_ptr), sizeof(FlatPtr) * 2)) {
if (!copy_from_user(&retaddr, &((FlatPtr*)stack_ptr)[1]) || !retaddr)
if (copy_from_user(&retaddr, &((FlatPtr*)stack_ptr)[1]).is_error() || !retaddr)
break;
stack_trace.append(retaddr);
if (!copy_from_user(&stack_ptr, (FlatPtr*)stack_ptr))
if (copy_from_user(&stack_ptr, (FlatPtr*)stack_ptr).is_error())
break;
} else {
void* fault_at;
@ -552,7 +552,7 @@ Vector<FlatPtr> Processor::capture_stack_trace(Thread& thread, size_t max_frames
auto& regs = thread.regs();
auto* stack_top = reinterpret_cast<FlatPtr*>(regs.sp());
if (Memory::is_user_range(VirtualAddress(stack_top), sizeof(FlatPtr))) {
if (!copy_from_user(&frame_ptr, &((FlatPtr*)stack_top)[0]))
if (copy_from_user(&frame_ptr, &((FlatPtr*)stack_top)[0]).is_error())
frame_ptr = 0;
} else {
void* fault_at;

View File

@ -316,9 +316,7 @@ KResult KeyboardDevice::ioctl(FileDescription&, unsigned request, Userspace<void
switch (request) {
case KEYBOARD_IOCTL_GET_NUM_LOCK: {
auto output = static_ptr_cast<bool*>(arg);
if (!copy_to_user(output, &m_num_lock_on))
return EFAULT;
return KSuccess;
return copy_to_user(output, &m_num_lock_on);
}
case KEYBOARD_IOCTL_SET_NUM_LOCK: {
// In this case we expect the value to be a boolean and not a pointer.
@ -330,9 +328,7 @@ KResult KeyboardDevice::ioctl(FileDescription&, unsigned request, Userspace<void
}
case KEYBOARD_IOCTL_GET_CAPS_LOCK: {
auto output = static_ptr_cast<bool*>(arg);
if (!copy_to_user(output, &m_caps_lock_on))
return EFAULT;
return KSuccess;
return copy_to_user(output, &m_caps_lock_on);
}
case KEYBOARD_IOCTL_SET_CAPS_LOCK: {
auto caps_lock_value = static_cast<u8>(arg.ptr());

View File

@ -127,9 +127,7 @@ KResult SB16::ioctl(FileDescription&, unsigned request, Userspace<void*> arg)
switch (request) {
case SOUNDCARD_IOCTL_GET_SAMPLE_RATE: {
auto output = static_ptr_cast<u16*>(arg);
if (!copy_to_user(output, &m_sample_rate))
return EFAULT;
return KSuccess;
return copy_to_user(output, &m_sample_rate);
}
case SOUNDCARD_IOCTL_SET_SAMPLE_RATE: {
auto sample_rate_value = static_cast<u16>(arg.ptr());

View File

@ -317,9 +317,7 @@ KResult Inode::can_apply_flock(FileDescription const& description, flock const&
KResult Inode::apply_flock(Process const& process, FileDescription const& description, Userspace<flock const*> input_lock)
{
flock new_lock = {};
if (!copy_from_user(&new_lock, input_lock))
return EFAULT;
TRY(copy_from_user(&new_lock, input_lock));
TRY(normalize_flock(description, new_lock));
MutexLocker locker(m_inode_lock);
@ -343,9 +341,7 @@ KResult Inode::apply_flock(Process const& process, FileDescription const& descri
KResult Inode::get_flock(FileDescription const& description, Userspace<flock*> reference_lock) const
{
flock lookup = {};
if (!copy_from_user(&lookup, reference_lock))
return EFAULT;
TRY(copy_from_user(&lookup, reference_lock));
TRY(normalize_flock(description, lookup));
MutexLocker locker(m_inode_lock, Mutex::Mode::Shared);
@ -356,16 +352,12 @@ KResult Inode::get_flock(FileDescription const& description, Userspace<flock*> r
if ((lookup.l_type == F_RDLCK && lock.type == F_WRLCK) || lookup.l_type == F_WRLCK) {
lookup = { lock.type, SEEK_SET, lock.start, lock.len, lock.pid };
if (!copy_to_user(reference_lock, &lookup))
return EFAULT;
return KSuccess;
return copy_to_user(reference_lock, &lookup);
}
}
lookup.l_type = F_UNLCK;
if (!copy_to_user(reference_lock, &lookup))
return EFAULT;
return KSuccess;
return copy_to_user(reference_lock, &lookup);
}
void Inode::remove_flocks_for_description(FileDescription const& description)

View File

@ -64,24 +64,17 @@ KResult InodeFile::ioctl(FileDescription& description, unsigned request, Userspa
auto user_block_number = static_ptr_cast<int*>(arg);
int block_number = 0;
if (!copy_from_user(&block_number, user_block_number))
return EFAULT;
TRY(copy_from_user(&block_number, user_block_number));
if (block_number < 0)
return EINVAL;
auto block_address = TRY(inode().get_block_address(block_number));
if (!copy_to_user(user_block_number, &block_address))
return EFAULT;
return KSuccess;
return copy_to_user(user_block_number, &block_address);
}
case FIONREAD: {
int remaining_bytes = inode().size() - description.offset();
if (!copy_to_user(Userspace<int*>(arg), &remaining_bytes))
return EFAULT;
return KSuccess;
return copy_to_user(Userspace<int*>(arg), &remaining_bytes);
}
default:
return EINVAL;

View File

@ -164,15 +164,12 @@ KResult FramebufferDevice::ioctl(FileDescription&, unsigned request, Userspace<v
case FB_IOCTL_GET_SIZE_IN_BYTES: {
auto user_size = static_ptr_cast<size_t*>(arg);
size_t value = framebuffer_size_in_bytes();
if (!copy_to_user(user_size, &value))
return EFAULT;
return KSuccess;
return copy_to_user(user_size, &value);
}
case FB_IOCTL_GET_BUFFER: {
auto user_index = static_ptr_cast<int*>(arg);
int value = m_y_offset == 0 ? 0 : 1;
if (!copy_to_user(user_index, &value))
return EFAULT;
TRY(copy_to_user(user_index, &value));
if (!m_graphics_adapter->double_framebuffering_capable())
return ENOTIMPL;
return KSuccess;
@ -192,15 +189,12 @@ KResult FramebufferDevice::ioctl(FileDescription&, unsigned request, Userspace<v
resolution.pitch = m_framebuffer_pitch;
resolution.width = m_framebuffer_width;
resolution.height = m_framebuffer_height;
if (!copy_to_user(user_resolution, &resolution))
return EFAULT;
return KSuccess;
return copy_to_user(user_resolution, &resolution);
}
case FB_IOCTL_SET_RESOLUTION: {
auto user_resolution = static_ptr_cast<FBResolution*>(arg);
FBResolution resolution;
if (!copy_from_user(&resolution, user_resolution))
return EFAULT;
TRY(copy_from_user(&resolution, user_resolution));
if (resolution.width > MAX_RESOLUTION_WIDTH || resolution.height > MAX_RESOLUTION_HEIGHT)
return EINVAL;
@ -208,8 +202,7 @@ KResult FramebufferDevice::ioctl(FileDescription&, unsigned request, Userspace<v
resolution.pitch = m_framebuffer_pitch;
resolution.width = m_framebuffer_width;
resolution.height = m_framebuffer_height;
if (!copy_to_user(user_resolution, &resolution))
return EFAULT;
TRY(copy_to_user(user_resolution, &resolution));
return ENOTIMPL;
}
@ -223,8 +216,7 @@ KResult FramebufferDevice::ioctl(FileDescription&, unsigned request, Userspace<v
resolution.pitch = m_framebuffer_pitch;
resolution.width = m_framebuffer_width;
resolution.height = m_framebuffer_height;
if (!copy_to_user(user_resolution, &resolution))
return EFAULT;
TRY(copy_to_user(user_resolution, &resolution));
return EINVAL;
}
m_framebuffer_width = resolution.width;
@ -235,21 +227,16 @@ KResult FramebufferDevice::ioctl(FileDescription&, unsigned request, Userspace<v
resolution.pitch = m_framebuffer_pitch;
resolution.width = m_framebuffer_width;
resolution.height = m_framebuffer_height;
if (!copy_to_user(user_resolution, &resolution))
return EFAULT;
return KSuccess;
return copy_to_user(user_resolution, &resolution);
}
case FB_IOCTL_GET_BUFFER_OFFSET: {
auto user_buffer_offset = static_ptr_cast<FBBufferOffset*>(arg);
FBBufferOffset buffer_offset;
if (!copy_from_user(&buffer_offset, user_buffer_offset))
return EFAULT;
TRY(copy_from_user(&buffer_offset, user_buffer_offset));
if (buffer_offset.buffer_index != 0 && buffer_offset.buffer_index != 1)
return EINVAL;
buffer_offset.offset = (size_t)buffer_offset.buffer_index * m_framebuffer_pitch * m_framebuffer_height;
if (!copy_to_user(user_buffer_offset, &buffer_offset))
return EFAULT;
return KSuccess;
return copy_to_user(user_buffer_offset, &buffer_offset);
}
case FB_IOCTL_FLUSH_BUFFERS:
return ENOTSUP;

View File

@ -158,21 +158,16 @@ KResult FrameBufferDevice::ioctl(FileDescription&, unsigned request, Userspace<v
case FB_IOCTL_GET_SIZE_IN_BYTES: {
auto out = static_ptr_cast<size_t*>(arg);
size_t value = m_buffer_size * 2;
if (!copy_to_user(out, &value))
return EFAULT;
return KSuccess;
return copy_to_user(out, &value);
}
case FB_IOCTL_SET_RESOLUTION: {
auto user_resolution = static_ptr_cast<FBResolution*>(arg);
FBResolution resolution;
if (!copy_from_user(&resolution, user_resolution))
return EFAULT;
TRY(copy_from_user(&resolution, user_resolution));
if (!try_to_set_resolution(resolution.width, resolution.height))
return EINVAL;
resolution.pitch = pitch();
if (!copy_to_user(user_resolution, &resolution))
return EFAULT;
return KSuccess;
return copy_to_user(user_resolution, &resolution);
}
case FB_IOCTL_GET_RESOLUTION: {
auto user_resolution = static_ptr_cast<FBResolution*>(arg);
@ -180,9 +175,7 @@ KResult FrameBufferDevice::ioctl(FileDescription&, unsigned request, Userspace<v
resolution.pitch = pitch();
resolution.width = width();
resolution.height = height();
if (!copy_to_user(user_resolution, &resolution))
return EFAULT;
return KSuccess;
return copy_to_user(user_resolution, &resolution);
}
case FB_IOCTL_SET_BUFFER: {
auto buffer_index = static_cast<int>(arg.ptr());
@ -195,8 +188,7 @@ KResult FrameBufferDevice::ioctl(FileDescription&, unsigned request, Userspace<v
case FB_IOCTL_FLUSH_BUFFERS: {
auto user_flush_rects = static_ptr_cast<FBFlushRects*>(arg);
FBFlushRects flush_rects;
if (!copy_from_user(&flush_rects, user_flush_rects))
return EFAULT;
TRY(copy_from_user(&flush_rects, user_flush_rects));
if (!is_valid_buffer_index(flush_rects.buffer_index))
return EINVAL;
if (Checked<unsigned>::multiplication_would_overflow(flush_rects.count, sizeof(FBRect)))
@ -206,8 +198,7 @@ KResult FrameBufferDevice::ioctl(FileDescription&, unsigned request, Userspace<v
MutexLocker locker(m_gpu.operation_lock());
for (unsigned i = 0; i < flush_rects.count; i++) {
FBRect user_dirty_rect;
if (!copy_from_user(&user_dirty_rect, &flush_rects.rects[i]))
return EFAULT;
TRY(copy_from_user(&user_dirty_rect, &flush_rects.rects[i]));
Protocol::Rect dirty_rect {
.x = user_dirty_rect.x,
.y = user_dirty_rect.y,
@ -238,14 +229,11 @@ KResult FrameBufferDevice::ioctl(FileDescription&, unsigned request, Userspace<v
case FB_IOCTL_GET_BUFFER_OFFSET: {
auto user_buffer_offset = static_ptr_cast<FBBufferOffset*>(arg);
FBBufferOffset buffer_offset;
if (!copy_from_user(&buffer_offset, user_buffer_offset))
return EFAULT;
TRY(copy_from_user(&buffer_offset, user_buffer_offset));
if (!is_valid_buffer_index(buffer_offset.buffer_index))
return EINVAL;
buffer_offset.offset = (size_t)buffer_offset.buffer_index * m_buffer_size;
if (!copy_to_user(user_buffer_offset, &buffer_offset))
return EFAULT;
return KSuccess;
return copy_to_user(user_buffer_offset, &buffer_offset);
}
default:
return EINVAL;

View File

@ -103,7 +103,7 @@ KResult IPv4Socket::bind(Userspace<const sockaddr*> user_address, socklen_t addr
return set_so_error(EINVAL);
sockaddr_in address;
if (!copy_from_user(&address, user_address, sizeof(sockaddr_in)))
if (copy_from_user(&address, user_address, sizeof(sockaddr_in)).is_error())
return set_so_error(EFAULT);
if (address.sin_family != AF_INET)
@ -147,7 +147,7 @@ KResult IPv4Socket::connect(FileDescription& description, Userspace<const sockad
return set_so_error(EINVAL);
u16 sa_family_copy;
auto* user_address = reinterpret_cast<const sockaddr*>(address.unsafe_userspace_ptr());
if (!copy_from_user(&sa_family_copy, &user_address->sa_family, sizeof(u16)))
if (copy_from_user(&sa_family_copy, &user_address->sa_family, sizeof(u16)).is_error())
return set_so_error(EFAULT);
if (sa_family_copy != AF_INET)
return set_so_error(EINVAL);
@ -155,7 +155,7 @@ KResult IPv4Socket::connect(FileDescription& description, Userspace<const sockad
return set_so_error(EISCONN);
sockaddr_in safe_address;
if (!copy_from_user(&safe_address, (const sockaddr_in*)user_address, sizeof(sockaddr_in)))
if (copy_from_user(&safe_address, (const sockaddr_in*)user_address, sizeof(sockaddr_in)).is_error())
return set_so_error(EFAULT);
m_peer_address = IPv4Address((const u8*)&safe_address.sin_addr.s_addr);
@ -201,7 +201,7 @@ KResultOr<size_t> IPv4Socket::sendto(FileDescription&, const UserOrKernelBuffer&
if (addr) {
sockaddr_in ia;
if (!copy_from_user(&ia, Userspace<const sockaddr_in*>(addr.ptr())))
if (copy_from_user(&ia, Userspace<const sockaddr_in*>(addr.ptr())).is_error())
return set_so_error(EFAULT);
if (ia.sin_family != AF_INET) {
@ -360,12 +360,12 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(FileDescription& descripti
out_addr.sin_port = htons(packet.peer_port);
out_addr.sin_family = AF_INET;
Userspace<sockaddr_in*> dest_addr = addr.ptr();
if (!copy_to_user(dest_addr, &out_addr))
if (copy_to_user(dest_addr, &out_addr).is_error())
return set_so_error(EFAULT);
socklen_t out_length = sizeof(sockaddr_in);
VERIFY(addr_length);
if (!copy_to_user(addr_length, &out_length))
if (copy_to_user(addr_length, &out_length).is_error())
return set_so_error(EFAULT);
}
@ -383,7 +383,7 @@ KResultOr<size_t> IPv4Socket::recvfrom(FileDescription& description, UserOrKerne
{
if (user_addr_length) {
socklen_t addr_length;
if (!copy_from_user(&addr_length, user_addr_length.unsafe_userspace_ptr()))
if (copy_from_user(&addr_length, user_addr_length.unsafe_userspace_ptr()).is_error())
return set_so_error(EFAULT);
if (addr_length < sizeof(sockaddr_in))
return set_so_error(EINVAL);
@ -492,8 +492,7 @@ KResult IPv4Socket::setsockopt(int level, int option, Userspace<const void*> use
if (user_value_size < sizeof(int))
return EINVAL;
int value;
if (!copy_from_user(&value, static_ptr_cast<const int*>(user_value)))
return EFAULT;
TRY(copy_from_user(&value, static_ptr_cast<const int*>(user_value)));
if (value < 0 || value > 255)
return EINVAL;
m_ttl = value;
@ -503,8 +502,7 @@ KResult IPv4Socket::setsockopt(int level, int option, Userspace<const void*> use
if (user_value_size != 1)
return EINVAL;
u8 value;
if (!copy_from_user(&value, static_ptr_cast<const u8*>(user_value)))
return EFAULT;
TRY(copy_from_user(&value, static_ptr_cast<const u8*>(user_value)));
if (value != 0 && value != 1)
return EINVAL;
m_multicast_loop = value;
@ -514,8 +512,7 @@ KResult IPv4Socket::setsockopt(int level, int option, Userspace<const void*> use
if (user_value_size != sizeof(ip_mreq))
return EINVAL;
ip_mreq mreq;
if (!copy_from_user(&mreq, static_ptr_cast<const ip_mreq*>(user_value)))
return EFAULT;
TRY(copy_from_user(&mreq, static_ptr_cast<const ip_mreq*>(user_value)));
if (mreq.imr_interface.s_addr != INADDR_ANY)
return ENOTSUP;
IPv4Address address { (const u8*)&mreq.imr_multiaddr.s_addr };
@ -527,8 +524,7 @@ KResult IPv4Socket::setsockopt(int level, int option, Userspace<const void*> use
if (user_value_size != sizeof(ip_mreq))
return EINVAL;
ip_mreq mreq;
if (!copy_from_user(&mreq, static_ptr_cast<const ip_mreq*>(user_value)))
return EFAULT;
TRY(copy_from_user(&mreq, static_ptr_cast<const ip_mreq*>(user_value)));
if (mreq.imr_interface.s_addr != INADDR_ANY)
return ENOTSUP;
IPv4Address address { (const u8*)&mreq.imr_multiaddr.s_addr };
@ -546,28 +542,21 @@ KResult IPv4Socket::getsockopt(FileDescription& description, int level, int opti
return Socket::getsockopt(description, level, option, value, value_size);
socklen_t size;
if (!copy_from_user(&size, value_size.unsafe_userspace_ptr()))
return EFAULT;
TRY(copy_from_user(&size, value_size.unsafe_userspace_ptr()));
switch (option) {
case IP_TTL:
if (size < sizeof(int))
return EINVAL;
if (!copy_to_user(static_ptr_cast<int*>(value), (int*)&m_ttl))
return EFAULT;
TRY(copy_to_user(static_ptr_cast<int*>(value), (int*)&m_ttl));
size = sizeof(int);
if (!copy_to_user(value_size, &size))
return EFAULT;
return KSuccess;
return copy_to_user(value_size, &size);
case IP_MULTICAST_LOOP: {
if (size < 1)
return EINVAL;
if (!copy_to_user(static_ptr_cast<u8*>(value), (const u8*)&m_multicast_loop))
return EFAULT;
TRY(copy_to_user(static_ptr_cast<u8*>(value), (const u8*)&m_multicast_loop));
size = 1;
if (!copy_to_user(value_size, &size))
return EFAULT;
return KSuccess;
return copy_to_user(value_size, &size);
}
default:
return ENOPROTOOPT;
@ -581,8 +570,7 @@ KResult IPv4Socket::ioctl(FileDescription&, unsigned request, Userspace<void*> a
auto ioctl_route = [request, arg]() -> KResult {
auto user_route = static_ptr_cast<rtentry*>(arg);
rtentry route;
if (!copy_from_user(&route, user_route))
return EFAULT;
TRY(copy_from_user(&route, user_route));
Userspace<const char*> user_rt_dev((FlatPtr)route.rt_dev);
auto ifname = TRY(try_copy_kstring_from_user(user_rt_dev, IFNAMSIZ));
@ -613,8 +601,7 @@ KResult IPv4Socket::ioctl(FileDescription&, unsigned request, Userspace<void*> a
auto ioctl_arp = [request, arg]() -> KResult {
auto user_req = static_ptr_cast<arpreq*>(arg);
arpreq arp_req;
if (!copy_from_user(&arp_req, user_req))
return EFAULT;
TRY(copy_from_user(&arp_req, user_req));
switch (request) {
case SIOCSARP:
@ -640,8 +627,7 @@ KResult IPv4Socket::ioctl(FileDescription&, unsigned request, Userspace<void*> a
auto ioctl_interface = [request, arg]() -> KResult {
auto user_ifr = static_ptr_cast<ifreq*>(arg);
ifreq ifr;
if (!copy_from_user(&ifr, user_ifr))
return EFAULT;
TRY(copy_from_user(&ifr, user_ifr));
char namebuf[IFNAMSIZ + 1];
memcpy(namebuf, ifr.ifr_name, IFNAMSIZ);
@ -673,9 +659,7 @@ KResult IPv4Socket::ioctl(FileDescription&, unsigned request, Userspace<void*> a
auto& socket_address_in = reinterpret_cast<sockaddr_in&>(ifr.ifr_addr);
socket_address_in.sin_family = AF_INET;
socket_address_in.sin_addr.s_addr = ip4_addr;
if (!copy_to_user(user_ifr, &ifr))
return EFAULT;
return KSuccess;
return copy_to_user(user_ifr, &ifr);
}
case SIOCGIFNETMASK: {
@ -685,18 +669,14 @@ KResult IPv4Socket::ioctl(FileDescription&, unsigned request, Userspace<void*> a
// NOTE: NOT ifr_netmask.
socket_address_in.sin_addr.s_addr = ip4_netmask;
if (!copy_to_user(user_ifr, &ifr))
return EFAULT;
return KSuccess;
return copy_to_user(user_ifr, &ifr);
}
case SIOCGIFHWADDR: {
auto mac_address = adapter->mac_address();
ifr.ifr_hwaddr.sa_family = AF_INET;
mac_address.copy_to(Bytes { ifr.ifr_hwaddr.sa_data, sizeof(ifr.ifr_hwaddr.sa_data) });
if (!copy_to_user(user_ifr, &ifr))
return EFAULT;
return KSuccess;
return copy_to_user(user_ifr, &ifr);
}
case SIOCGIFBRDADDR: {
@ -707,9 +687,7 @@ KResult IPv4Socket::ioctl(FileDescription&, unsigned request, Userspace<void*> a
auto& socket_address_in = reinterpret_cast<sockaddr_in&>(ifr.ifr_addr);
socket_address_in.sin_family = AF_INET;
socket_address_in.sin_addr.s_addr = broadcast_addr;
if (!copy_to_user(user_ifr, &ifr))
return EFAULT;
return KSuccess;
return copy_to_user(user_ifr, &ifr);
}
case SIOCGIFMTU: {
@ -717,9 +695,7 @@ KResult IPv4Socket::ioctl(FileDescription&, unsigned request, Userspace<void*> a
ifr.ifr_addr.sa_family = AF_INET;
ifr.ifr_metric = ip4_metric;
if (!copy_to_user(user_ifr, &ifr))
return EFAULT;
return KSuccess;
return copy_to_user(user_ifr, &ifr);
}
case SIOCGIFFLAGS: {
@ -727,9 +703,7 @@ KResult IPv4Socket::ioctl(FileDescription&, unsigned request, Userspace<void*> a
constexpr short flags = 1;
ifr.ifr_addr.sa_family = AF_INET;
ifr.ifr_flags = flags;
if (!copy_to_user(user_ifr, &ifr))
return EFAULT;
return KSuccess;
return copy_to_user(user_ifr, &ifr);
}
case SIOCGIFCONF: {
@ -763,10 +737,7 @@ KResult IPv4Socket::ioctl(FileDescription&, unsigned request, Userspace<void*> a
case FIONREAD: {
int readable = m_receive_buffer->immediately_readable();
if (!copy_to_user(Userspace<int*>(arg), &readable))
return EFAULT;
return KSuccess;
return copy_to_user(Userspace<int*>(arg), &readable);
}
}
@ -791,4 +762,5 @@ void IPv4Socket::set_can_read(bool value)
if (value)
evaluate_block_conditions();
}
}

View File

@ -121,7 +121,7 @@ KResult LocalSocket::bind(Userspace<const sockaddr*> user_address, socklen_t add
return set_so_error(EINVAL);
sockaddr_un address = {};
if (!copy_from_user(&address, user_address, sizeof(sockaddr_un)))
if (copy_from_user(&address, user_address, sizeof(sockaddr_un)).is_error())
return set_so_error(EFAULT);
if (address.sun_family != AF_LOCAL)
@ -162,7 +162,7 @@ KResult LocalSocket::connect(FileDescription& description, Userspace<const socka
return set_so_error(EINVAL);
u16 sa_family_copy;
auto* user_address = reinterpret_cast<const sockaddr*>(address.unsafe_userspace_ptr());
if (!copy_from_user(&sa_family_copy, &user_address->sa_family, sizeof(u16)))
if (copy_from_user(&sa_family_copy, &user_address->sa_family, sizeof(u16)).is_error())
return set_so_error(EFAULT);
if (sa_family_copy != AF_LOCAL)
return set_so_error(EINVAL);
@ -173,7 +173,7 @@ KResult LocalSocket::connect(FileDescription& description, Userspace<const socka
{
auto const& local_address = *reinterpret_cast<sockaddr_un const*>(user_address);
char safe_address[sizeof(local_address.sun_path) + 1] = { 0 };
if (!copy_from_user(&safe_address[0], &local_address.sun_path[0], sizeof(safe_address) - 1))
if (copy_from_user(&safe_address[0], &local_address.sun_path[0], sizeof(safe_address) - 1).is_error())
return set_so_error(EFAULT);
safe_address[sizeof(safe_address) - 1] = '\0';
maybe_path = KString::try_create(safe_address);
@ -398,8 +398,7 @@ KResult LocalSocket::getsockopt(FileDescription& description, int level, int opt
return Socket::getsockopt(description, level, option, value, value_size);
socklen_t size;
if (!copy_from_user(&size, value_size.unsafe_userspace_ptr()))
return EFAULT;
TRY(copy_from_user(&size, value_size.unsafe_userspace_ptr()));
switch (option) {
case SO_SNDBUF:
@ -411,18 +410,14 @@ KResult LocalSocket::getsockopt(FileDescription& description, int level, int opt
return EINVAL;
switch (role(description)) {
case Role::Accepted:
if (!copy_to_user(static_ptr_cast<ucred*>(value), &m_origin))
return EFAULT;
TRY(copy_to_user(static_ptr_cast<ucred*>(value), &m_origin));
size = sizeof(ucred);
if (!copy_to_user(value_size, &size))
return EFAULT;
TRY(copy_to_user(value_size, &size));
return KSuccess;
case Role::Connected:
if (!copy_to_user(static_ptr_cast<ucred*>(value), &m_acceptor))
return EFAULT;
TRY(copy_to_user(static_ptr_cast<ucred*>(value), &m_acceptor));
size = sizeof(ucred);
if (!copy_to_user(value_size, &size))
return EFAULT;
TRY(copy_to_user(value_size, &size));
return KSuccess;
case Role::Connecting:
return ENOTCONN;
@ -441,10 +436,7 @@ KResult LocalSocket::ioctl(FileDescription& description, unsigned request, Users
switch (request) {
case FIONREAD: {
int readable = receive_buffer_for(description)->immediately_readable();
if (!copy_to_user(Userspace<int*>(arg), &readable))
return EFAULT;
return KSuccess;
return copy_to_user(Userspace<int*>(arg), &readable);
}
}

View File

@ -128,8 +128,7 @@ KResult Socket::setsockopt(int level, int option, Userspace<const void*> user_va
return EINVAL;
{
int timestamp;
if (!copy_from_user(&timestamp, static_ptr_cast<const int*>(user_value)))
return EFAULT;
TRY(copy_from_user(&timestamp, static_ptr_cast<const int*>(user_value)));
m_timestamp = timestamp;
}
if (m_timestamp && (domain() != AF_INET || type() == SOCK_STREAM)) {
@ -147,8 +146,7 @@ KResult Socket::setsockopt(int level, int option, Userspace<const void*> user_va
KResult Socket::getsockopt(FileDescription&, int level, int option, Userspace<void*> value, Userspace<socklen_t*> value_size)
{
socklen_t size;
if (!copy_from_user(&size, value_size.unsafe_userspace_ptr()))
return EFAULT;
TRY(copy_from_user(&size, value_size.unsafe_userspace_ptr()));
// FIXME: Add TCP_NODELAY, IPPROTO_TCP and IPPROTO_IP (used in OpenSSH)
if (level != SOL_SOCKET) {
@ -162,34 +160,26 @@ KResult Socket::getsockopt(FileDescription&, int level, int option, Userspace<vo
return EINVAL;
{
timeval tv = m_send_timeout.to_timeval();
if (!copy_to_user(static_ptr_cast<timeval*>(value), &tv))
return EFAULT;
TRY(copy_to_user(static_ptr_cast<timeval*>(value), &tv));
}
size = sizeof(timeval);
if (!copy_to_user(value_size, &size))
return EFAULT;
return KSuccess;
return copy_to_user(value_size, &size);
case SO_RCVTIMEO:
if (size < sizeof(timeval))
return EINVAL;
{
timeval tv = m_send_timeout.to_timeval();
if (!copy_to_user(static_ptr_cast<timeval*>(value), &tv))
return EFAULT;
TRY(copy_to_user(static_ptr_cast<timeval*>(value), &tv));
}
size = sizeof(timeval);
if (!copy_to_user(value_size, &size))
return EFAULT;
return KSuccess;
return copy_to_user(value_size, &size);
case SO_ERROR: {
if (size < sizeof(int))
return EINVAL;
int errno = so_error().error();
if (!copy_to_user(static_ptr_cast<int*>(value), &errno))
return EFAULT;
TRY(copy_to_user(static_ptr_cast<int*>(value), &errno));
size = sizeof(int);
if (!copy_to_user(value_size, &size))
return EFAULT;
TRY(copy_to_user(value_size, &size));
return set_so_error(KSuccess);
}
case SO_BINDTODEVICE:
@ -198,28 +188,21 @@ KResult Socket::getsockopt(FileDescription&, int level, int option, Userspace<vo
if (m_bound_interface) {
const auto& name = m_bound_interface->name();
auto length = name.length() + 1;
if (!copy_to_user(static_ptr_cast<char*>(value), name.characters(), length))
return EFAULT;
TRY(copy_to_user(static_ptr_cast<char*>(value), name.characters(), length));
size = length;
if (!copy_to_user(value_size, &size))
return EFAULT;
return KSuccess;
return copy_to_user(value_size, &size);
} else {
size = 0;
if (!copy_to_user(value_size, &size))
return EFAULT;
TRY(copy_to_user(value_size, &size));
// FIXME: This return value looks suspicious.
return EFAULT;
}
case SO_TIMESTAMP:
if (size < sizeof(int))
return EINVAL;
if (!copy_to_user(static_ptr_cast<int*>(value), &m_timestamp))
return EFAULT;
TRY(copy_to_user(static_ptr_cast<int*>(value), &m_timestamp));
size = sizeof(int);
if (!copy_to_user(value_size, &size))
return EFAULT;
return KSuccess;
return copy_to_user(value_size, &size);
default:
dbgln("setsockopt({}) at SOL_SOCKET not implemented.", option);
return ENOPROTOOPT;

View File

@ -418,7 +418,7 @@ public:
KResultOr<FlatPtr> sys$map_time_page();
template<bool sockname, typename Params>
int get_sock_or_peer_name(const Params&);
KResult get_sock_or_peer_name(Params const&);
static void initialize();

View File

@ -45,7 +45,7 @@ Kernel::KResultOr<NonnullOwnPtr<Kernel::KString>> try_copy_kstring_from_user(Use
[[nodiscard]] Optional<Time> copy_time_from_user(const timespec* ts_user)
{
timespec ts;
if (!copy_from_user(&ts, ts_user, sizeof(timespec))) {
if (copy_from_user(&ts, ts_user, sizeof(timespec)).is_error()) {
return {};
}
return Time::from_timespec(ts);
@ -53,7 +53,7 @@ Kernel::KResultOr<NonnullOwnPtr<Kernel::KString>> try_copy_kstring_from_user(Use
[[nodiscard]] Optional<Time> copy_time_from_user(const timeval* tv_user)
{
timeval tv;
if (!copy_from_user(&tv, tv_user, sizeof(timeval))) {
if (copy_from_user(&tv, tv_user, sizeof(timeval)).is_error()) {
return {};
}
return Time::from_timeval(tv);
@ -168,57 +168,55 @@ Optional<u32> user_atomic_fetch_xor_relaxed(volatile u32* var, u32 val)
return Kernel::safe_atomic_fetch_xor_relaxed(var, val);
}
extern "C" {
bool copy_to_user(void* dest_ptr, const void* src_ptr, size_t n)
KResult copy_to_user(void* dest_ptr, void const* src_ptr, size_t n)
{
bool is_user = Kernel::Memory::is_user_range(VirtualAddress(dest_ptr), n);
if (!is_user)
return false;
if (!Kernel::Memory::is_user_range(VirtualAddress(dest_ptr), n))
return EFAULT;
VERIFY(!Kernel::Memory::is_user_range(VirtualAddress(src_ptr), n));
Kernel::SmapDisabler disabler;
void* fault_at;
if (!Kernel::safe_memcpy(dest_ptr, src_ptr, n, fault_at)) {
VERIFY(VirtualAddress(fault_at) >= VirtualAddress(dest_ptr) && VirtualAddress(fault_at) <= VirtualAddress((FlatPtr)dest_ptr + n));
dbgln("copy_to_user({:p}, {:p}, {}) failed at {}", dest_ptr, src_ptr, n, VirtualAddress { fault_at });
return false;
return EFAULT;
}
return true;
return KSuccess;
}
bool copy_from_user(void* dest_ptr, const void* src_ptr, size_t n)
KResult copy_from_user(void* dest_ptr, void const* src_ptr, size_t n)
{
bool is_user = Kernel::Memory::is_user_range(VirtualAddress(src_ptr), n);
if (!is_user)
return false;
if (!Kernel::Memory::is_user_range(VirtualAddress(src_ptr), n))
return EFAULT;
VERIFY(!Kernel::Memory::is_user_range(VirtualAddress(dest_ptr), n));
Kernel::SmapDisabler disabler;
void* fault_at;
if (!Kernel::safe_memcpy(dest_ptr, src_ptr, n, fault_at)) {
VERIFY(VirtualAddress(fault_at) >= VirtualAddress(src_ptr) && VirtualAddress(fault_at) <= VirtualAddress((FlatPtr)src_ptr + n));
dbgln("copy_from_user({:p}, {:p}, {}) failed at {}", dest_ptr, src_ptr, n, VirtualAddress { fault_at });
return false;
return EFAULT;
}
return true;
return KSuccess;
}
const void* memmem(const void* haystack, size_t haystack_length, const void* needle, size_t needle_length)
{
return AK::memmem(haystack, haystack_length, needle, needle_length);
}
[[nodiscard]] bool memset_user(void* dest_ptr, int c, size_t n)
[[nodiscard]] KResult memset_user(void* dest_ptr, int c, size_t n)
{
bool is_user = Kernel::Memory::is_user_range(VirtualAddress(dest_ptr), n);
if (!is_user)
return false;
return EFAULT;
Kernel::SmapDisabler disabler;
void* fault_at;
if (!Kernel::safe_memset(dest_ptr, c, n, fault_at)) {
dbgln("memset_user({:p}, {}, {}) failed at {}", dest_ptr, c, n, VirtualAddress { fault_at });
return false;
return EFAULT;
}
return true;
return KSuccess;
}
extern "C" {
const void* memmem(const void* haystack, size_t haystack_length, const void* needle, size_t needle_length)
{
return AK::memmem(haystack, haystack_length, needle, needle_length);
}
size_t strnlen(const char* str, size_t maxlen)

View File

@ -34,11 +34,11 @@ template<typename T>
[[nodiscard]] Optional<u32> user_atomic_fetch_or_relaxed(volatile u32* var, u32 val);
[[nodiscard]] Optional<u32> user_atomic_fetch_xor_relaxed(volatile u32* var, u32 val);
extern "C" {
[[nodiscard]] KResult copy_to_user(void*, const void*, size_t);
[[nodiscard]] KResult copy_from_user(void*, const void*, size_t);
[[nodiscard]] KResult memset_user(void*, int, size_t);
[[nodiscard]] bool copy_to_user(void*, const void*, size_t);
[[nodiscard]] bool copy_from_user(void*, const void*, size_t);
[[nodiscard]] bool memset_user(void*, int, size_t);
extern "C" {
void* memcpy(void*, const void*, size_t);
[[nodiscard]] int strncmp(const char* s1, const char* s2, size_t n);
@ -56,114 +56,114 @@ const void* memmem(const void* haystack, size_t, const void* needle, size_t);
}
template<typename T>
[[nodiscard]] inline bool copy_from_user(T* dest, const T* src)
[[nodiscard]] inline KResult copy_from_user(T* dest, const T* src)
{
static_assert(IsTriviallyCopyable<T>);
return copy_from_user(dest, src, sizeof(T));
}
template<typename T>
[[nodiscard]] inline bool copy_to_user(T* dest, const T* src)
[[nodiscard]] inline KResult copy_to_user(T* dest, const T* src)
{
static_assert(IsTriviallyCopyable<T>);
return copy_to_user(dest, src, sizeof(T));
}
template<typename T>
[[nodiscard]] inline bool copy_from_user(T* dest, Userspace<const T*> src)
[[nodiscard]] inline KResult copy_from_user(T* dest, Userspace<const T*> src)
{
static_assert(IsTriviallyCopyable<T>);
return copy_from_user(dest, src.unsafe_userspace_ptr(), sizeof(T));
}
template<typename T>
[[nodiscard]] inline bool copy_from_user(T* dest, Userspace<T*> src)
[[nodiscard]] inline KResult copy_from_user(T* dest, Userspace<T*> src)
{
static_assert(IsTriviallyCopyable<T>);
return copy_from_user(dest, src.unsafe_userspace_ptr(), sizeof(T));
}
#define DEPRECATE_COPY_FROM_USER_TYPE(T, REPLACEMENT) \
template<> \
[[nodiscard]] inline __attribute__((deprecated("use " #REPLACEMENT " instead"))) bool copy_from_user<T>(T*, const T*) \
{ \
VERIFY_NOT_REACHED(); \
} \
template<> \
[[nodiscard]] inline __attribute__((deprecated("use " #REPLACEMENT " instead"))) bool copy_from_user<T>(T*, Userspace<const T*>) \
{ \
VERIFY_NOT_REACHED(); \
} \
template<> \
[[nodiscard]] inline __attribute__((deprecated("use " #REPLACEMENT " instead"))) bool copy_from_user<T>(T*, Userspace<T*>) \
{ \
VERIFY_NOT_REACHED(); \
#define DEPRECATE_COPY_FROM_USER_TYPE(T, REPLACEMENT) \
template<> \
[[nodiscard]] inline __attribute__((deprecated("use " #REPLACEMENT " instead"))) KResult copy_from_user<T>(T*, const T*) \
{ \
VERIFY_NOT_REACHED(); \
} \
template<> \
[[nodiscard]] inline __attribute__((deprecated("use " #REPLACEMENT " instead"))) KResult copy_from_user<T>(T*, Userspace<const T*>) \
{ \
VERIFY_NOT_REACHED(); \
} \
template<> \
[[nodiscard]] inline __attribute__((deprecated("use " #REPLACEMENT " instead"))) KResult copy_from_user<T>(T*, Userspace<T*>) \
{ \
VERIFY_NOT_REACHED(); \
}
DEPRECATE_COPY_FROM_USER_TYPE(timespec, copy_time_from_user)
DEPRECATE_COPY_FROM_USER_TYPE(timeval, copy_time_from_user)
template<typename T>
[[nodiscard]] inline bool copy_to_user(Userspace<T*> dest, const T* src)
[[nodiscard]] inline KResult copy_to_user(Userspace<T*> dest, const T* src)
{
static_assert(IsTriviallyCopyable<T>);
return copy_to_user(dest.unsafe_userspace_ptr(), src, sizeof(T));
}
template<typename T>
[[nodiscard]] inline bool copy_to_user(Userspace<T*> dest, const void* src, size_t size)
[[nodiscard]] inline KResult copy_to_user(Userspace<T*> dest, const void* src, size_t size)
{
static_assert(IsTriviallyCopyable<T>);
return copy_to_user(dest.unsafe_userspace_ptr(), src, size);
}
template<typename T>
[[nodiscard]] inline bool copy_from_user(void* dest, Userspace<const T*> src, size_t size)
[[nodiscard]] inline KResult copy_from_user(void* dest, Userspace<const T*> src, size_t size)
{
static_assert(IsTriviallyCopyable<T>);
return copy_from_user(dest, src.unsafe_userspace_ptr(), size);
}
template<typename T>
[[nodiscard]] inline bool copy_n_from_user(T* dest, const T* src, size_t count)
[[nodiscard]] inline KResult copy_n_from_user(T* dest, const T* src, size_t count)
{
static_assert(IsTriviallyCopyable<T>);
Checked<size_t> size = sizeof(T);
size *= count;
if (size.has_overflow())
return false;
return EOVERFLOW;
return copy_from_user(dest, src, size.value());
}
template<typename T>
[[nodiscard]] inline bool copy_n_to_user(T* dest, const T* src, size_t count)
[[nodiscard]] inline KResult copy_n_to_user(T* dest, const T* src, size_t count)
{
static_assert(IsTriviallyCopyable<T>);
Checked<size_t> size = sizeof(T);
size *= count;
if (size.has_overflow())
return false;
return EOVERFLOW;
return copy_to_user(dest, src, size.value());
}
template<typename T>
[[nodiscard]] inline bool copy_n_from_user(T* dest, Userspace<const T*> src, size_t count)
[[nodiscard]] inline KResult copy_n_from_user(T* dest, Userspace<const T*> src, size_t count)
{
static_assert(IsTriviallyCopyable<T>);
Checked<size_t> size = sizeof(T);
size *= count;
if (size.has_overflow())
return false;
return EOVERFLOW;
return copy_from_user(dest, src.unsafe_userspace_ptr(), size.value());
}
template<typename T>
[[nodiscard]] inline bool copy_n_to_user(Userspace<T*> dest, const T* src, size_t count)
[[nodiscard]] inline KResult try_copy_n_to_user(Userspace<T*> dest, const T* src, size_t count)
{
static_assert(IsTriviallyCopyable<T>);
Checked<size_t> size = sizeof(T);
size *= count;
if (size.has_overflow())
return false;
return EOVERFLOW;
return copy_to_user(dest.unsafe_userspace_ptr(), src, size.value());
}

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())

View File

@ -472,9 +472,7 @@ KResult TTY::ioctl(FileDescription&, unsigned request, Userspace<void*> arg)
case TIOCGPGRP: {
auto user_pgid = static_ptr_cast<pid_t*>(arg);
auto pgid = this->pgid().value();
if (!copy_to_user(user_pgid, &pgid))
return EFAULT;
return KSuccess;
return copy_to_user(user_pgid, &pgid);
}
case TIOCSPGRP: {
ProcessGroupID pgid = static_cast<pid_t>(arg.ptr());
@ -506,17 +504,14 @@ KResult TTY::ioctl(FileDescription&, unsigned request, Userspace<void*> arg)
}
case TCGETS: {
user_termios = static_ptr_cast<termios*>(arg);
if (!copy_to_user(user_termios, &m_termios))
return EFAULT;
return KSuccess;
return copy_to_user(user_termios, &m_termios);
}
case TCSETS:
case TCSETSF:
case TCSETSW: {
user_termios = static_ptr_cast<termios*>(arg);
termios termios;
if (!copy_from_user(&termios, user_termios))
return EFAULT;
TRY(copy_from_user(&termios, user_termios));
auto rc = set_termios(termios);
if (request == TCSETSF)
flush_input();
@ -539,14 +534,11 @@ KResult TTY::ioctl(FileDescription&, unsigned request, Userspace<void*> arg)
ws.ws_col = m_columns;
ws.ws_xpixel = 0;
ws.ws_ypixel = 0;
if (!copy_to_user(user_winsize, &ws))
return EFAULT;
return KSuccess;
return copy_to_user(user_winsize, &ws);
case TIOCSWINSZ: {
user_winsize = static_ptr_cast<winsize*>(arg);
winsize ws;
if (!copy_from_user(&ws, user_winsize))
return EFAULT;
TRY(copy_from_user(&ws, user_winsize));
if (ws.ws_col == m_columns && ws.ws_row == m_rows)
return KSuccess;
m_rows = ws.ws_row;

View File

@ -802,10 +802,11 @@ bool Thread::has_signal_handler(u8 signal) const
return !action.handler_or_sigaction.is_null();
}
static bool push_value_on_user_stack(FlatPtr& stack, FlatPtr data)
static void push_value_on_user_stack(FlatPtr& stack, FlatPtr data)
{
stack -= sizeof(FlatPtr);
return copy_to_user((FlatPtr*)stack, &data);
auto result = copy_to_user((FlatPtr*)stack, &data);
VERIFY(result.is_success());
}
void Thread::resume_from_stopped()

View File

@ -24,8 +24,7 @@ KResultOr<NonnullOwnPtr<KString>> UserOrKernelBuffer::try_copy_into_kstring(size
auto kstring = KString::try_create_uninitialized(size, buffer);
if (!kstring)
return ENOMEM;
if (!copy_from_user(buffer, m_buffer, size))
return EFAULT;
TRY(copy_from_user(buffer, m_buffer, size));
return kstring.release_nonnull();
}
@ -41,7 +40,7 @@ bool UserOrKernelBuffer::write(const void* src, size_t offset, size_t len)
return false;
if (Memory::is_user_address(VirtualAddress(m_buffer)))
return copy_to_user(m_buffer + offset, src, len);
return copy_to_user(m_buffer + offset, src, len).is_success();
memcpy(m_buffer + offset, src, len);
return true;
@ -53,7 +52,7 @@ bool UserOrKernelBuffer::read(void* dest, size_t offset, size_t len) const
return false;
if (Memory::is_user_address(VirtualAddress(m_buffer)))
return copy_from_user(dest, m_buffer + offset, len);
return copy_from_user(dest, m_buffer + offset, len).is_success();
memcpy(dest, m_buffer + offset, len);
return true;
@ -65,7 +64,7 @@ bool UserOrKernelBuffer::memset(int value, size_t offset, size_t len)
return false;
if (Memory::is_user_address(VirtualAddress(m_buffer)))
return memset_user(m_buffer + offset, value, len);
return memset_user(m_buffer + offset, value, len).is_success();
::memset(m_buffer + offset, value, len);
return true;