mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-28 21:54:40 +03:00
Kernel: Make copy_{from,to}_user() return KResult and use TRY()
This makes EFAULT propagation flow much more naturally. :^)
This commit is contained in:
parent
9903f5c6ef
commit
48a0b31c47
Notes:
sideshowbarker
2024-07-18 04:41:52 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/48a0b31c478
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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());
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,8 +128,7 @@ KResult Socket::setsockopt(int level, int option, Userspace<const void*> user_va
|
||||
return EINVAL;
|
||||
{
|
||||
int timestamp;
|
||||
if (!copy_from_user(×tamp, static_ptr_cast<const int*>(user_value)))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(×tamp, 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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -52,8 +52,7 @@ KResultOr<FlatPtr> Process::sys$getcwd(Userspace<char*> buffer, size_t size)
|
||||
|
||||
size_t ideal_size = path.length() + 1;
|
||||
auto size_to_copy = min(ideal_size, size);
|
||||
if (!copy_to_user(buffer, path.characters(), size_to_copy))
|
||||
return EFAULT;
|
||||
TRY(copy_to_user(buffer, path.characters(), size_to_copy));
|
||||
// Note: we return the whole size here, not the copied size.
|
||||
return ideal_size;
|
||||
}
|
||||
|
@ -24,8 +24,7 @@ KResultOr<FlatPtr> Process::sys$chown(Userspace<const Syscall::SC_chown_params*>
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||
REQUIRE_PROMISE(chown);
|
||||
Syscall::SC_chown_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
auto path = TRY(get_syscall_path_argument(params.path));
|
||||
return VirtualFileSystem::the().chown(path->view(), params.uid, params.gid, current_directory());
|
||||
}
|
||||
|
@ -37,10 +37,7 @@ KResultOr<FlatPtr> Process::sys$clock_gettime(clockid_t clock_id, Userspace<time
|
||||
return EINVAL;
|
||||
|
||||
auto ts = TimeManagement::the().current_time(clock_id).to_timespec();
|
||||
if (!copy_to_user(user_ts, &ts))
|
||||
return EFAULT;
|
||||
|
||||
return 0;
|
||||
return copy_to_user(user_ts, &ts);
|
||||
}
|
||||
|
||||
KResultOr<FlatPtr> Process::sys$clock_settime(clockid_t clock_id, Userspace<const timespec*> user_ts)
|
||||
@ -71,8 +68,7 @@ KResultOr<FlatPtr> Process::sys$clock_nanosleep(Userspace<const Syscall::SC_cloc
|
||||
REQUIRE_PROMISE(stdio);
|
||||
|
||||
Syscall::SC_clock_nanosleep_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
Optional<Time> requested_sleep = copy_time_from_user(params.requested_sleep);
|
||||
if (!requested_sleep.has_value())
|
||||
@ -100,8 +96,9 @@ KResultOr<FlatPtr> Process::sys$clock_nanosleep(Userspace<const Syscall::SC_cloc
|
||||
Time remaining_sleep;
|
||||
was_interrupted = Thread::current()->sleep(params.clock_id, requested_sleep.value(), &remaining_sleep).was_interrupted();
|
||||
timespec remaining_sleep_ts = remaining_sleep.to_timespec();
|
||||
if (was_interrupted && params.remaining_sleep && !copy_to_user(params.remaining_sleep, &remaining_sleep_ts))
|
||||
return EFAULT;
|
||||
if (was_interrupted && params.remaining_sleep) {
|
||||
TRY(copy_to_user(params.remaining_sleep, &remaining_sleep_ts));
|
||||
}
|
||||
}
|
||||
if (was_interrupted)
|
||||
return EINTR;
|
||||
@ -115,8 +112,7 @@ KResultOr<FlatPtr> Process::sys$adjtime(Userspace<const timeval*> user_delta, Us
|
||||
timespec old_delta_ts = TimeManagement::the().remaining_epoch_time_adjustment();
|
||||
timeval old_delta;
|
||||
timespec_to_timeval(old_delta_ts, old_delta);
|
||||
if (!copy_to_user(user_old_delta, &old_delta))
|
||||
return EFAULT;
|
||||
TRY(copy_to_user(user_old_delta, &old_delta));
|
||||
}
|
||||
|
||||
if (user_delta) {
|
||||
|
@ -33,8 +33,7 @@ KResultOr<FlatPtr> Process::sys$dbgputstr(Userspace<const char*> characters, siz
|
||||
|
||||
if (size <= 1024) {
|
||||
char buffer[1024];
|
||||
if (!copy_from_user(buffer, characters, size))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(buffer, characters, size));
|
||||
dbgputstr(buffer, size);
|
||||
return size;
|
||||
}
|
||||
|
@ -79,19 +79,22 @@ static KResultOr<FlatPtr> make_userspace_context_for_main_thread([[maybe_unused]
|
||||
auto push_on_new_stack = [&new_sp](FlatPtr value) {
|
||||
new_sp -= sizeof(FlatPtr);
|
||||
Userspace<FlatPtr*> stack_ptr = new_sp;
|
||||
return copy_to_user(stack_ptr, &value);
|
||||
auto result = copy_to_user(stack_ptr, &value);
|
||||
VERIFY(result.is_success());
|
||||
};
|
||||
|
||||
auto push_aux_value_on_new_stack = [&new_sp](auxv_t value) {
|
||||
new_sp -= sizeof(auxv_t);
|
||||
Userspace<auxv_t*> stack_ptr = new_sp;
|
||||
return copy_to_user(stack_ptr, &value);
|
||||
auto result = copy_to_user(stack_ptr, &value);
|
||||
VERIFY(result.is_success());
|
||||
};
|
||||
|
||||
auto push_string_on_new_stack = [&new_sp](const String& string) {
|
||||
new_sp -= round_up_to_power_of_two(string.length() + 1, sizeof(FlatPtr));
|
||||
Userspace<FlatPtr*> stack_ptr = new_sp;
|
||||
return copy_to_user(stack_ptr, string.characters(), string.length() + 1);
|
||||
auto result = copy_to_user(stack_ptr, string.characters(), string.length() + 1);
|
||||
VERIFY(result.is_success());
|
||||
};
|
||||
|
||||
Vector<FlatPtr> argv_entries;
|
||||
@ -329,7 +332,7 @@ static KResultOr<LoadResult> load_elf_object(NonnullOwnPtr<Memory::AddressSpace>
|
||||
master_tls_size = program_header.size_in_memory();
|
||||
master_tls_alignment = program_header.alignment();
|
||||
|
||||
if (!copy_to_user(master_tls_region->vaddr().as_ptr(), program_header.raw_data(), program_header.size_in_image())) {
|
||||
if (copy_to_user(master_tls_region->vaddr().as_ptr(), program_header.raw_data(), program_header.size_in_image()).is_error()) {
|
||||
ph_load_result = EFAULT;
|
||||
return IterationDecision::Break;
|
||||
}
|
||||
@ -382,7 +385,7 @@ static KResultOr<LoadResult> load_elf_object(NonnullOwnPtr<Memory::AddressSpace>
|
||||
// Accessing it would definitely be a bug.
|
||||
auto page_offset = program_header.vaddr();
|
||||
page_offset.mask(~PAGE_MASK);
|
||||
if (!copy_to_user((u8*)region_or_error.value()->vaddr().as_ptr() + page_offset.get(), program_header.raw_data(), program_header.size_in_image())) {
|
||||
if (copy_to_user((u8*)region_or_error.value()->vaddr().as_ptr() + page_offset.get(), program_header.raw_data(), program_header.size_in_image()).is_error()) {
|
||||
ph_load_result = EFAULT;
|
||||
return IterationDecision::Break;
|
||||
}
|
||||
@ -937,8 +940,7 @@ KResultOr<FlatPtr> Process::sys$execve(Userspace<const Syscall::SC_execve_params
|
||||
// NOTE: Be extremely careful with allocating any kernel memory in exec().
|
||||
// On success, the kernel stack will be lost.
|
||||
Syscall::SC_execve_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
if (params.arguments.length > ARG_MAX || params.environment.length > ARG_MAX)
|
||||
return E2BIG;
|
||||
@ -961,7 +963,7 @@ KResultOr<FlatPtr> Process::sys$execve(Userspace<const Syscall::SC_execve_params
|
||||
Vector<Syscall::StringArgument, 32> strings;
|
||||
if (!strings.try_resize(list.length))
|
||||
return false;
|
||||
if (!copy_from_user(strings.data(), list.strings, size.value()))
|
||||
if (copy_from_user(strings.data(), list.strings, size.value()).is_error())
|
||||
return false;
|
||||
for (size_t i = 0; i < list.length; ++i) {
|
||||
auto string_or_error = try_copy_kstring_from_user(strings[i]);
|
||||
|
@ -14,8 +14,7 @@ KResultOr<FlatPtr> Process::sys$ftruncate(int fd, Userspace<off_t*> userspace_le
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
REQUIRE_PROMISE(stdio);
|
||||
off_t length;
|
||||
if (!copy_from_user(&length, userspace_length))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(&length, userspace_length));
|
||||
if (length < 0)
|
||||
return EINVAL;
|
||||
auto description = fds().file_description(fd);
|
||||
|
@ -26,8 +26,7 @@ KResultOr<FlatPtr> Process::sys$futex(Userspace<const Syscall::SC_futex_params*>
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||
Syscall::SC_futex_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
Thread::BlockTimeout timeout;
|
||||
u32 cmd = params.futex_op & FUTEX_CMD_MASK;
|
||||
|
@ -21,11 +21,8 @@ KResultOr<FlatPtr> Process::sys$get_stack_bounds(Userspace<FlatPtr*> user_stack_
|
||||
|
||||
FlatPtr stack_base = stack_region->range().base().get();
|
||||
size_t stack_size = stack_region->size();
|
||||
if (!copy_to_user(user_stack_base, &stack_base))
|
||||
return EFAULT;
|
||||
if (!copy_to_user(user_stack_size, &stack_size))
|
||||
return EFAULT;
|
||||
return 0;
|
||||
TRY(copy_to_user(user_stack_base, &stack_base));
|
||||
return copy_to_user(user_stack_size, &stack_size);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -40,18 +40,20 @@ KResultOr<FlatPtr> Process::sys$getresuid(Userspace<UserID*> ruid, Userspace<Use
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
REQUIRE_PROMISE(stdio);
|
||||
if (!copy_to_user(ruid, &m_protected_values.uid) || !copy_to_user(euid, &m_protected_values.euid) || !copy_to_user(suid, &m_protected_values.suid))
|
||||
return EFAULT;
|
||||
return 0;
|
||||
TRY(copy_to_user(ruid, &m_protected_values.uid));
|
||||
TRY(copy_to_user(euid, &m_protected_values.euid));
|
||||
TRY(copy_to_user(suid, &m_protected_values.suid));
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
KResultOr<FlatPtr> Process::sys$getresgid(Userspace<GroupID*> rgid, Userspace<GroupID*> egid, Userspace<GroupID*> sgid)
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
REQUIRE_PROMISE(stdio);
|
||||
if (!copy_to_user(rgid, &m_protected_values.gid) || !copy_to_user(egid, &m_protected_values.egid) || !copy_to_user(sgid, &m_protected_values.sgid))
|
||||
return EFAULT;
|
||||
return 0;
|
||||
TRY(copy_to_user(rgid, &m_protected_values.gid));
|
||||
TRY(copy_to_user(egid, &m_protected_values.egid));
|
||||
TRY(copy_to_user(sgid, &m_protected_values.sgid));
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
KResultOr<FlatPtr> Process::sys$getgroups(size_t count, Userspace<gid_t*> user_gids)
|
||||
@ -62,11 +64,7 @@ KResultOr<FlatPtr> Process::sys$getgroups(size_t count, Userspace<gid_t*> user_g
|
||||
return extra_gids().size();
|
||||
if (count != extra_gids().size())
|
||||
return EINVAL;
|
||||
|
||||
if (!copy_to_user(user_gids, extra_gids().data(), sizeof(gid_t) * count))
|
||||
return EFAULT;
|
||||
|
||||
return 0;
|
||||
return copy_to_user(user_gids, extra_gids().data(), sizeof(gid_t) * count);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,8 +17,7 @@ KResultOr<FlatPtr> Process::sys$gethostname(Userspace<char*> buffer, size_t size
|
||||
return hostname().with_shared([&](const auto& name) -> KResultOr<FlatPtr> {
|
||||
if (size < (name.length() + 1))
|
||||
return ENAMETOOLONG;
|
||||
if (!copy_to_user(buffer, name.characters(), name.length() + 1))
|
||||
return EFAULT;
|
||||
TRY(copy_to_user(buffer, name.characters(), name.length() + 1));
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
@ -48,8 +48,7 @@ KResultOr<FlatPtr> Process::sys$inode_watcher_add_watch(Userspace<const Syscall:
|
||||
REQUIRE_PROMISE(rpath);
|
||||
|
||||
Syscall::SC_inode_watcher_add_watch_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
auto description = fds().file_description(params.fd);
|
||||
if (!description)
|
||||
|
@ -20,21 +20,15 @@ KResultOr<FlatPtr> Process::sys$setkeymap(Userspace<const Syscall::SC_setkeymap_
|
||||
return EPERM;
|
||||
|
||||
Syscall::SC_setkeymap_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
Keyboard::CharacterMapData character_map_data;
|
||||
|
||||
if (!copy_n_from_user(character_map_data.map, params.map, CHAR_MAP_SIZE))
|
||||
return EFAULT;
|
||||
if (!copy_n_from_user(character_map_data.shift_map, params.shift_map, CHAR_MAP_SIZE))
|
||||
return EFAULT;
|
||||
if (!copy_n_from_user(character_map_data.alt_map, params.alt_map, CHAR_MAP_SIZE))
|
||||
return EFAULT;
|
||||
if (!copy_n_from_user(character_map_data.altgr_map, params.altgr_map, CHAR_MAP_SIZE))
|
||||
return EFAULT;
|
||||
if (!copy_n_from_user(character_map_data.shift_altgr_map, params.shift_altgr_map, CHAR_MAP_SIZE))
|
||||
return EFAULT;
|
||||
TRY(copy_n_from_user(character_map_data.map, params.map, CHAR_MAP_SIZE));
|
||||
TRY(copy_n_from_user(character_map_data.shift_map, params.shift_map, CHAR_MAP_SIZE));
|
||||
TRY(copy_n_from_user(character_map_data.alt_map, params.alt_map, CHAR_MAP_SIZE));
|
||||
TRY(copy_n_from_user(character_map_data.altgr_map, params.altgr_map, CHAR_MAP_SIZE));
|
||||
TRY(copy_n_from_user(character_map_data.shift_altgr_map, params.shift_altgr_map, CHAR_MAP_SIZE));
|
||||
|
||||
auto map_name = get_syscall_path_argument(params.map_name);
|
||||
if (map_name.is_error())
|
||||
@ -51,30 +45,22 @@ KResultOr<FlatPtr> Process::sys$getkeymap(Userspace<const Syscall::SC_getkeymap_
|
||||
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
||||
REQUIRE_PROMISE(getkeymap);
|
||||
|
||||
Syscall::SC_getkeymap_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
Syscall::SC_getkeymap_params params {};
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
String keymap_name = HIDManagement::the().keymap_name();
|
||||
const Keyboard::CharacterMapData& character_maps = HIDManagement::the().character_maps();
|
||||
|
||||
if (!copy_to_user(params.map, character_maps.map, CHAR_MAP_SIZE * sizeof(u32)))
|
||||
return EFAULT;
|
||||
if (!copy_to_user(params.shift_map, character_maps.shift_map, CHAR_MAP_SIZE * sizeof(u32)))
|
||||
return EFAULT;
|
||||
if (!copy_to_user(params.alt_map, character_maps.alt_map, CHAR_MAP_SIZE * sizeof(u32)))
|
||||
return EFAULT;
|
||||
if (!copy_to_user(params.altgr_map, character_maps.altgr_map, CHAR_MAP_SIZE * sizeof(u32)))
|
||||
return EFAULT;
|
||||
if (!copy_to_user(params.shift_altgr_map, character_maps.shift_altgr_map, CHAR_MAP_SIZE * sizeof(u32)))
|
||||
return EFAULT;
|
||||
TRY(copy_to_user(params.map, character_maps.map, CHAR_MAP_SIZE * sizeof(u32)));
|
||||
TRY(copy_to_user(params.shift_map, character_maps.shift_map, CHAR_MAP_SIZE * sizeof(u32)));
|
||||
TRY(copy_to_user(params.alt_map, character_maps.alt_map, CHAR_MAP_SIZE * sizeof(u32)));
|
||||
TRY(copy_to_user(params.altgr_map, character_maps.altgr_map, CHAR_MAP_SIZE * sizeof(u32)));
|
||||
TRY(copy_to_user(params.shift_altgr_map, character_maps.shift_altgr_map, CHAR_MAP_SIZE * sizeof(u32)));
|
||||
|
||||
if (params.map_name.size < keymap_name.length())
|
||||
return ENAMETOOLONG;
|
||||
if (!copy_to_user(params.map_name.data, keymap_name.characters(), keymap_name.length()))
|
||||
return EFAULT;
|
||||
|
||||
return 0;
|
||||
TRY(copy_to_user(params.map_name.data, keymap_name.characters(), keymap_name.length()));
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,8 +15,7 @@ KResultOr<FlatPtr> Process::sys$link(Userspace<const Syscall::SC_link_params*> u
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
REQUIRE_PROMISE(cpath);
|
||||
Syscall::SC_link_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
auto old_path = TRY(try_copy_kstring_from_user(params.old_path));
|
||||
auto new_path = TRY(try_copy_kstring_from_user(params.new_path));
|
||||
return VirtualFileSystem::the().link(old_path->view(), new_path->view(), current_directory());
|
||||
@ -27,8 +26,7 @@ KResultOr<FlatPtr> Process::sys$symlink(Userspace<const Syscall::SC_symlink_para
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
REQUIRE_PROMISE(cpath);
|
||||
Syscall::SC_symlink_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
auto target = TRY(get_syscall_path_argument(params.target));
|
||||
auto linkpath = TRY(get_syscall_path_argument(params.linkpath));
|
||||
return VirtualFileSystem::the().symlink(target->view(), linkpath->view(), current_directory());
|
||||
|
@ -17,12 +17,9 @@ KResultOr<FlatPtr> Process::sys$lseek(int fd, Userspace<off_t*> userspace_offset
|
||||
if (!description)
|
||||
return EBADF;
|
||||
off_t offset;
|
||||
if (!copy_from_user(&offset, userspace_offset))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(&offset, userspace_offset));
|
||||
auto seek_result = TRY(description->seek(offset, whence));
|
||||
if (!copy_to_user(userspace_offset, &seek_result))
|
||||
return EFAULT;
|
||||
return KSuccess;
|
||||
return copy_to_user(userspace_offset, &seek_result);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,8 +15,7 @@ KResultOr<FlatPtr> Process::sys$mknod(Userspace<const Syscall::SC_mknod_params*>
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
REQUIRE_PROMISE(dpath);
|
||||
Syscall::SC_mknod_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
if (!is_superuser() && !is_regular_file(params.mode) && !is_fifo(params.mode) && !is_socket(params.mode))
|
||||
return EPERM;
|
||||
auto path = TRY(get_syscall_path_argument(params.path));
|
||||
|
@ -130,8 +130,7 @@ KResultOr<FlatPtr> Process::sys$mmap(Userspace<const Syscall::SC_mmap_params*> u
|
||||
REQUIRE_PROMISE(stdio);
|
||||
|
||||
Syscall::SC_mmap_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
FlatPtr addr = params.addr;
|
||||
auto size = params.size;
|
||||
@ -470,8 +469,7 @@ KResultOr<FlatPtr> Process::sys$set_mmap_name(Userspace<const Syscall::SC_set_mm
|
||||
REQUIRE_PROMISE(stdio);
|
||||
|
||||
Syscall::SC_set_mmap_name_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
if (params.name.length > PATH_MAX)
|
||||
return ENAMETOOLONG;
|
||||
@ -508,8 +506,7 @@ KResultOr<FlatPtr> Process::sys$mremap(Userspace<const Syscall::SC_mremap_params
|
||||
REQUIRE_PROMISE(stdio);
|
||||
|
||||
Syscall::SC_mremap_params params {};
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
auto old_range = TRY(expand_range_to_page_boundaries((FlatPtr)params.old_address, params.old_size));
|
||||
|
||||
|
@ -27,8 +27,7 @@ KResultOr<FlatPtr> Process::sys$mount(Userspace<const Syscall::SC_mount_params*>
|
||||
REQUIRE_NO_PROMISES;
|
||||
|
||||
Syscall::SC_mount_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
auto source_fd = params.source_fd;
|
||||
auto target_or_error = try_copy_kstring_from_user(params.target);
|
||||
|
@ -15,8 +15,7 @@ KResultOr<FlatPtr> Process::sys$open(Userspace<const Syscall::SC_open_params*> u
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
Syscall::SC_open_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
int dirfd = params.dirfd;
|
||||
int options = params.options;
|
||||
|
@ -36,12 +36,9 @@ KResultOr<FlatPtr> Process::sys$pipe(int pipefd[2], int flags)
|
||||
m_fds[reader_fd_allocation.fd].set(move(reader_description), fd_flags);
|
||||
m_fds[writer_fd_allocation.fd].set(move(writer_description), fd_flags);
|
||||
|
||||
if (!copy_to_user(&pipefd[0], &reader_fd_allocation.fd))
|
||||
return EFAULT;
|
||||
if (!copy_to_user(&pipefd[1], &writer_fd_allocation.fd))
|
||||
return EFAULT;
|
||||
|
||||
return 0;
|
||||
TRY(copy_to_user(&pipefd[0], &reader_fd_allocation.fd));
|
||||
TRY(copy_to_user(&pipefd[1], &writer_fd_allocation.fd));
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,8 +13,7 @@ KResultOr<FlatPtr> Process::sys$pledge(Userspace<const Syscall::SC_pledge_params
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
Syscall::SC_pledge_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
if (params.promises.length > 1024 || params.execpromises.length > 1024)
|
||||
return E2BIG;
|
||||
|
@ -30,9 +30,7 @@ KResultOr<FlatPtr> Process::sys$get_process_name(Userspace<char*> buffer, size_t
|
||||
if (m_name.length() + 1 > buffer_size)
|
||||
return ENAMETOOLONG;
|
||||
|
||||
if (!copy_to_user(buffer, m_name.characters(), m_name.length() + 1))
|
||||
return EFAULT;
|
||||
return 0;
|
||||
return copy_to_user(buffer, m_name.characters(), m_name.length() + 1);
|
||||
}
|
||||
|
||||
KResultOr<FlatPtr> Process::sys$set_process_name(Userspace<const char*> user_name, size_t user_name_length)
|
||||
@ -56,8 +54,7 @@ KResultOr<FlatPtr> Process::sys$set_coredump_metadata(Userspace<const Syscall::S
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
Syscall::SC_set_coredump_metadata_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
if (params.key.length == 0 || params.key.length > 16 * KiB)
|
||||
return EINVAL;
|
||||
if (params.value.length > 16 * KiB)
|
||||
|
@ -92,8 +92,7 @@ static KResultOr<u32> handle_ptrace(const Kernel::Syscall::SC_ptrace_params& par
|
||||
if (!tracer->has_regs())
|
||||
return EINVAL;
|
||||
auto* regs = reinterpret_cast<PtraceRegisters*>(params.addr);
|
||||
if (!copy_to_user(regs, &tracer->regs()))
|
||||
return EFAULT;
|
||||
TRY(copy_to_user(regs, &tracer->regs()));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -102,8 +101,7 @@ static KResultOr<u32> handle_ptrace(const Kernel::Syscall::SC_ptrace_params& par
|
||||
return EINVAL;
|
||||
|
||||
PtraceRegisters regs {};
|
||||
if (!copy_from_user(®s, (const PtraceRegisters*)params.addr))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(®s, (const PtraceRegisters*)params.addr));
|
||||
|
||||
auto& peer_saved_registers = peer->get_register_dump_from_stack();
|
||||
// Verify that the saved registers are in usermode context
|
||||
@ -117,13 +115,11 @@ static KResultOr<u32> handle_ptrace(const Kernel::Syscall::SC_ptrace_params& par
|
||||
|
||||
case PT_PEEK: {
|
||||
Kernel::Syscall::SC_ptrace_peek_params peek_params {};
|
||||
if (!copy_from_user(&peek_params, reinterpret_cast<Kernel::Syscall::SC_ptrace_peek_params*>(params.addr)))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(&peek_params, reinterpret_cast<Kernel::Syscall::SC_ptrace_peek_params*>(params.addr)));
|
||||
if (!Memory::is_user_address(VirtualAddress { peek_params.address }))
|
||||
return EFAULT;
|
||||
auto data = TRY(peer->process().peek_user_data(Userspace<const u32*> { (FlatPtr)peek_params.address }));
|
||||
if (!copy_to_user(peek_params.out_data, &data))
|
||||
return EFAULT;
|
||||
TRY(copy_to_user(peek_params.out_data, &data));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -134,11 +130,9 @@ static KResultOr<u32> handle_ptrace(const Kernel::Syscall::SC_ptrace_params& par
|
||||
|
||||
case PT_PEEKDEBUG: {
|
||||
Kernel::Syscall::SC_ptrace_peek_params peek_params {};
|
||||
if (!copy_from_user(&peek_params, reinterpret_cast<Kernel::Syscall::SC_ptrace_peek_params*>(params.addr)))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(&peek_params, reinterpret_cast<Kernel::Syscall::SC_ptrace_peek_params*>(params.addr)));
|
||||
auto data = TRY(peer->peek_debug_register(reinterpret_cast<uintptr_t>(peek_params.address)));
|
||||
if (!copy_to_user(peek_params.out_data, &data))
|
||||
return EFAULT;
|
||||
TRY(copy_to_user(peek_params.out_data, &data));
|
||||
break;
|
||||
}
|
||||
case PT_POKEDEBUG:
|
||||
@ -155,8 +149,7 @@ KResultOr<FlatPtr> Process::sys$ptrace(Userspace<const Syscall::SC_ptrace_params
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
REQUIRE_PROMISE(ptrace);
|
||||
Syscall::SC_ptrace_params params {};
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
auto result = handle_ptrace(params, *this);
|
||||
return result.is_error() ? result.error().error() : result.value();
|
||||
}
|
||||
@ -173,17 +166,12 @@ bool Process::has_tracee_thread(ProcessID tracer_pid)
|
||||
|
||||
KResultOr<u32> Process::peek_user_data(Userspace<const u32*> address)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
// This function can be called from the context of another
|
||||
// process that called PT_PEEK
|
||||
ProcessPagingScope scope(*this);
|
||||
if (!copy_from_user(&result, address)) {
|
||||
dbgln("Invalid address for peek_user_data: {}", address.ptr());
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
return result;
|
||||
uint32_t data;
|
||||
TRY(copy_from_user(&data, address));
|
||||
return data;
|
||||
}
|
||||
|
||||
KResult Process::poke_user_data(Userspace<u32*> address, u32 data)
|
||||
@ -215,12 +203,7 @@ KResult Process::poke_user_data(Userspace<u32*> address, u32 data)
|
||||
}
|
||||
});
|
||||
|
||||
if (!copy_to_user(address, &data)) {
|
||||
dbgln("poke_user_data: Bad address {:p}", address.ptr());
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
return KSuccess;
|
||||
return copy_to_user(address, &data);
|
||||
}
|
||||
|
||||
KResultOr<u32> Thread::peek_debug_register(u32 register_index)
|
||||
|
@ -27,8 +27,7 @@ KResultOr<FlatPtr> Process::sys$readv(int fd, Userspace<const struct iovec*> iov
|
||||
Vector<iovec, 32> vecs;
|
||||
if (!vecs.try_resize(iov_count))
|
||||
return ENOMEM;
|
||||
if (!copy_n_from_user(vecs.data(), iov, iov_count))
|
||||
return EFAULT;
|
||||
TRY(copy_n_from_user(vecs.data(), iov, iov_count));
|
||||
for (auto& vec : vecs) {
|
||||
total_length += vec.iov_len;
|
||||
if (total_length > NumericLimits<i32>::max())
|
||||
|
@ -16,8 +16,7 @@ KResultOr<FlatPtr> Process::sys$readlink(Userspace<const Syscall::SC_readlink_pa
|
||||
REQUIRE_PROMISE(rpath);
|
||||
|
||||
Syscall::SC_readlink_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
auto path = get_syscall_path_argument(params.path);
|
||||
if (path.is_error())
|
||||
@ -37,8 +36,7 @@ KResultOr<FlatPtr> Process::sys$readlink(Userspace<const Syscall::SC_readlink_pa
|
||||
|
||||
auto& link_target = *contents.value();
|
||||
auto size_to_copy = min(link_target.size(), params.buffer.size);
|
||||
if (!copy_to_user(params.buffer.data, link_target.data(), size_to_copy))
|
||||
return EFAULT;
|
||||
TRY(copy_to_user(params.buffer.data, link_target.data(), size_to_copy));
|
||||
// Note: we return the whole size here, not the copied size.
|
||||
return link_target.size();
|
||||
}
|
||||
|
@ -17,8 +17,7 @@ KResultOr<FlatPtr> Process::sys$realpath(Userspace<const Syscall::SC_realpath_pa
|
||||
REQUIRE_PROMISE(rpath);
|
||||
|
||||
Syscall::SC_realpath_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
auto path = get_syscall_path_argument(params.path);
|
||||
if (path.is_error())
|
||||
@ -34,8 +33,7 @@ KResultOr<FlatPtr> Process::sys$realpath(Userspace<const Syscall::SC_realpath_pa
|
||||
|
||||
size_t ideal_size = absolute_path->length() + 1;
|
||||
auto size_to_copy = min(ideal_size, params.buffer.size);
|
||||
if (!copy_to_user(params.buffer.data, absolute_path->characters(), size_to_copy))
|
||||
return EFAULT;
|
||||
TRY(copy_to_user(params.buffer.data, absolute_path->characters(), size_to_copy));
|
||||
// Note: we return the whole size here, not the copied size.
|
||||
return ideal_size;
|
||||
};
|
||||
|
@ -15,8 +15,7 @@ KResultOr<FlatPtr> Process::sys$rename(Userspace<const Syscall::SC_rename_params
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
REQUIRE_PROMISE(cpath);
|
||||
Syscall::SC_rename_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
auto old_path = get_syscall_path_argument(params.old_path);
|
||||
if (old_path.is_error())
|
||||
return old_path.error();
|
||||
|
@ -21,8 +21,7 @@ KResultOr<FlatPtr> Process::sys$sched_setparam(int pid, Userspace<const struct s
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
REQUIRE_PROMISE(proc);
|
||||
struct sched_param desired_param;
|
||||
if (!copy_from_user(&desired_param, user_param))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(&desired_param, user_param));
|
||||
|
||||
if (desired_param.sched_priority < THREAD_PRIORITY_MIN || desired_param.sched_priority > THREAD_PRIORITY_MAX)
|
||||
return EINVAL;
|
||||
@ -68,9 +67,8 @@ KResultOr<FlatPtr> Process::sys$sched_getparam(pid_t pid, Userspace<struct sched
|
||||
struct sched_param param {
|
||||
priority
|
||||
};
|
||||
if (!copy_to_user(user_param, ¶m))
|
||||
return EFAULT;
|
||||
return 0;
|
||||
|
||||
return copy_to_user(user_param, ¶m);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,8 +20,7 @@ KResultOr<FlatPtr> Process::sys$select(Userspace<const Syscall::SC_select_params
|
||||
REQUIRE_PROMISE(stdio);
|
||||
Syscall::SC_select_params params {};
|
||||
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
if (params.nfds < 0)
|
||||
return EINVAL;
|
||||
@ -39,8 +38,7 @@ KResultOr<FlatPtr> Process::sys$select(Userspace<const Syscall::SC_select_params
|
||||
u32 previous_signal_mask = 0;
|
||||
if (params.sigmask) {
|
||||
sigset_t sigmask_copy;
|
||||
if (!copy_from_user(&sigmask_copy, params.sigmask))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(&sigmask_copy, params.sigmask));
|
||||
previous_signal_mask = current_thread->update_signal_mask(sigmask_copy);
|
||||
}
|
||||
ScopeGuard rollback_signal_mask([&]() {
|
||||
@ -54,12 +52,14 @@ KResultOr<FlatPtr> Process::sys$select(Userspace<const Syscall::SC_select_params
|
||||
if (bytes_used > sizeof(fds_read))
|
||||
return EINVAL;
|
||||
|
||||
if (params.readfds && !copy_from_user(&fds_read, params.readfds, bytes_used))
|
||||
return EFAULT;
|
||||
if (params.writefds && !copy_from_user(&fds_write, params.writefds, bytes_used))
|
||||
return EFAULT;
|
||||
if (params.exceptfds && !copy_from_user(&fds_except, params.exceptfds, bytes_used))
|
||||
return EFAULT;
|
||||
if (params.readfds)
|
||||
TRY(copy_from_user(&fds_read, params.readfds, bytes_used));
|
||||
|
||||
if (params.writefds)
|
||||
TRY(copy_from_user(&fds_write, params.writefds, bytes_used));
|
||||
|
||||
if (params.exceptfds)
|
||||
TRY(copy_from_user(&fds_except, params.exceptfds, bytes_used));
|
||||
|
||||
Thread::SelectBlocker::FDVector fds_info;
|
||||
Vector<int, FD_SETSIZE> selected_fds;
|
||||
@ -119,12 +119,12 @@ KResultOr<FlatPtr> Process::sys$select(Userspace<const Syscall::SC_select_params
|
||||
}
|
||||
}
|
||||
|
||||
if (params.readfds && !copy_to_user(params.readfds, &fds_read, bytes_used))
|
||||
return EFAULT;
|
||||
if (params.writefds && !copy_to_user(params.writefds, &fds_write, bytes_used))
|
||||
return EFAULT;
|
||||
if (params.exceptfds && !copy_to_user(params.exceptfds, &fds_except, bytes_used))
|
||||
return EFAULT;
|
||||
if (params.readfds)
|
||||
TRY(copy_to_user(params.readfds, &fds_read, bytes_used));
|
||||
if (params.writefds)
|
||||
TRY(copy_to_user(params.writefds, &fds_write, bytes_used));
|
||||
if (params.exceptfds)
|
||||
TRY(copy_to_user(params.exceptfds, &fds_except, bytes_used));
|
||||
return marked_fd_count;
|
||||
}
|
||||
|
||||
@ -133,9 +133,8 @@ KResultOr<FlatPtr> Process::sys$poll(Userspace<const Syscall::SC_poll_params*> u
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
REQUIRE_PROMISE(stdio);
|
||||
|
||||
Syscall::SC_poll_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
Syscall::SC_poll_params params {};
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
if (params.nfds >= fds().max_open())
|
||||
return ENOBUFS;
|
||||
@ -149,8 +148,8 @@ KResultOr<FlatPtr> Process::sys$poll(Userspace<const Syscall::SC_poll_params*> u
|
||||
}
|
||||
|
||||
sigset_t sigmask = {};
|
||||
if (params.sigmask && !copy_from_user(&sigmask, params.sigmask))
|
||||
return EFAULT;
|
||||
if (params.sigmask)
|
||||
TRY(copy_from_user(&sigmask, params.sigmask));
|
||||
|
||||
Vector<pollfd, FD_SETSIZE> fds_copy;
|
||||
if (params.nfds > 0) {
|
||||
@ -160,8 +159,7 @@ KResultOr<FlatPtr> Process::sys$poll(Userspace<const Syscall::SC_poll_params*> u
|
||||
return EFAULT;
|
||||
if (!fds_copy.try_resize(params.nfds))
|
||||
return ENOMEM;
|
||||
if (!copy_from_user(fds_copy.data(), ¶ms.fds[0], nfds_checked.value()))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(fds_copy.data(), ¶ms.fds[0], nfds_checked.value()));
|
||||
}
|
||||
|
||||
Thread::SelectBlocker::FDVector fds_info;
|
||||
@ -234,8 +232,8 @@ KResultOr<FlatPtr> Process::sys$poll(Userspace<const Syscall::SC_poll_params*> u
|
||||
fds_with_revents++;
|
||||
}
|
||||
|
||||
if (params.nfds > 0 && !copy_to_user(¶ms.fds[0], fds_copy.data(), params.nfds * sizeof(pollfd)))
|
||||
return EFAULT;
|
||||
if (params.nfds > 0)
|
||||
TRY(copy_to_user(¶ms.fds[0], fds_copy.data(), params.nfds * sizeof(pollfd)));
|
||||
|
||||
return fds_with_revents;
|
||||
}
|
||||
|
@ -171,8 +171,7 @@ KResultOr<FlatPtr> Process::sys$setgroups(size_t count, Userspace<const gid_t*>
|
||||
Vector<gid_t> new_extra_gids;
|
||||
if (!new_extra_gids.try_resize(count))
|
||||
return ENOMEM;
|
||||
if (!copy_n_from_user(new_extra_gids.data(), user_gids, count))
|
||||
return EFAULT;
|
||||
TRY(copy_n_from_user(new_extra_gids.data(), user_gids, count));
|
||||
|
||||
HashTable<gid_t> unique_extra_gids;
|
||||
for (auto& extra_gid : new_extra_gids) {
|
||||
|
@ -18,8 +18,7 @@ KResultOr<FlatPtr> Process::sys$sigprocmask(int how, Userspace<const sigset_t*>
|
||||
u32 previous_signal_mask;
|
||||
if (set) {
|
||||
sigset_t set_value;
|
||||
if (!copy_from_user(&set_value, set))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(&set_value, set));
|
||||
switch (how) {
|
||||
case SIG_BLOCK:
|
||||
previous_signal_mask = current_thread->signal_mask_block(set_value, true);
|
||||
@ -36,8 +35,9 @@ KResultOr<FlatPtr> Process::sys$sigprocmask(int how, Userspace<const sigset_t*>
|
||||
} else {
|
||||
previous_signal_mask = current_thread->signal_mask();
|
||||
}
|
||||
if (old_set && !copy_to_user(old_set, &previous_signal_mask))
|
||||
return EFAULT;
|
||||
if (old_set) {
|
||||
TRY(copy_to_user(old_set, &previous_signal_mask));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -46,9 +46,7 @@ KResultOr<FlatPtr> Process::sys$sigpending(Userspace<sigset_t*> set)
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
REQUIRE_PROMISE(stdio);
|
||||
auto pending_signals = Thread::current()->pending_signals();
|
||||
if (!copy_to_user(set, &pending_signals))
|
||||
return EFAULT;
|
||||
return 0;
|
||||
return copy_to_user(set, &pending_signals);
|
||||
}
|
||||
|
||||
KResultOr<FlatPtr> Process::sys$sigaction(int signum, Userspace<const sigaction*> user_act, Userspace<sigaction*> user_old_act)
|
||||
@ -64,13 +62,11 @@ KResultOr<FlatPtr> Process::sys$sigaction(int signum, Userspace<const sigaction*
|
||||
sigaction old_act {};
|
||||
old_act.sa_flags = action.flags;
|
||||
old_act.sa_sigaction = reinterpret_cast<decltype(old_act.sa_sigaction)>(action.handler_or_sigaction.as_ptr());
|
||||
if (!copy_to_user(user_old_act, &old_act))
|
||||
return EFAULT;
|
||||
TRY(copy_to_user(user_old_act, &old_act));
|
||||
}
|
||||
if (user_act) {
|
||||
sigaction act {};
|
||||
if (!copy_from_user(&act, user_act))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(&act, user_act));
|
||||
action.flags = act.sa_flags;
|
||||
action.handler_or_sigaction = VirtualAddress { reinterpret_cast<void*>(act.sa_sigaction) };
|
||||
}
|
||||
|
@ -80,9 +80,8 @@ KResultOr<FlatPtr> Process::sys$accept4(Userspace<const Syscall::SC_accept4_para
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
REQUIRE_PROMISE(accept);
|
||||
|
||||
Syscall::SC_accept4_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
Syscall::SC_accept4_params params = {};
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
int accepting_socket_fd = params.sockfd;
|
||||
Userspace<sockaddr*> user_address((FlatPtr)params.addr);
|
||||
@ -90,8 +89,9 @@ KResultOr<FlatPtr> Process::sys$accept4(Userspace<const Syscall::SC_accept4_para
|
||||
int flags = params.flags;
|
||||
|
||||
socklen_t address_size = 0;
|
||||
if (user_address && !copy_from_user(&address_size, static_ptr_cast<const socklen_t*>(user_address_size)))
|
||||
return EFAULT;
|
||||
if (user_address) {
|
||||
TRY(copy_from_user(&address_size, static_ptr_cast<const socklen_t*>(user_address_size)));
|
||||
}
|
||||
|
||||
auto fd_allocation = TRY(m_fds.allocate());
|
||||
auto accepting_socket_description = fds().file_description(accepting_socket_fd);
|
||||
@ -117,10 +117,8 @@ KResultOr<FlatPtr> Process::sys$accept4(Userspace<const Syscall::SC_accept4_para
|
||||
sockaddr_un address_buffer;
|
||||
address_size = min(sizeof(sockaddr_un), static_cast<size_t>(address_size));
|
||||
accepted_socket->get_peer_address((sockaddr*)&address_buffer, &address_size);
|
||||
if (!copy_to_user(user_address, &address_buffer, address_size))
|
||||
return EFAULT;
|
||||
if (!copy_to_user(user_address_size, &address_size))
|
||||
return EFAULT;
|
||||
TRY(copy_to_user(user_address, &address_buffer, address_size));
|
||||
TRY(copy_to_user(user_address_size, &address_size));
|
||||
}
|
||||
|
||||
auto accepted_socket_description = TRY(FileDescription::try_create(*accepted_socket));
|
||||
@ -175,17 +173,15 @@ KResultOr<FlatPtr> Process::sys$sendmsg(int sockfd, Userspace<const struct msghd
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
REQUIRE_PROMISE(stdio);
|
||||
struct msghdr msg;
|
||||
if (!copy_from_user(&msg, user_msg))
|
||||
return EFAULT;
|
||||
struct msghdr msg = {};
|
||||
TRY(copy_from_user(&msg, user_msg));
|
||||
|
||||
if (msg.msg_iovlen != 1)
|
||||
return ENOTSUP; // FIXME: Support this :)
|
||||
Vector<iovec, 1> iovs;
|
||||
if (!iovs.try_resize(msg.msg_iovlen))
|
||||
return ENOMEM;
|
||||
if (!copy_n_from_user(iovs.data(), msg.msg_iov, msg.msg_iovlen))
|
||||
return EFAULT;
|
||||
TRY(copy_n_from_user(iovs.data(), msg.msg_iov, msg.msg_iovlen));
|
||||
if (iovs[0].iov_len > NumericLimits<ssize_t>::max())
|
||||
return EINVAL;
|
||||
|
||||
@ -216,16 +212,14 @@ KResultOr<FlatPtr> Process::sys$recvmsg(int sockfd, Userspace<struct msghdr*> us
|
||||
REQUIRE_PROMISE(stdio);
|
||||
|
||||
struct msghdr msg;
|
||||
if (!copy_from_user(&msg, user_msg))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(&msg, user_msg));
|
||||
|
||||
if (msg.msg_iovlen != 1)
|
||||
return ENOTSUP; // FIXME: Support this :)
|
||||
Vector<iovec, 1> iovs;
|
||||
if (!iovs.try_resize(msg.msg_iovlen))
|
||||
return ENOMEM;
|
||||
if (!copy_n_from_user(iovs.data(), msg.msg_iov, msg.msg_iovlen))
|
||||
return EFAULT;
|
||||
TRY(copy_n_from_user(iovs.data(), msg.msg_iov, msg.msg_iovlen));
|
||||
|
||||
Userspace<sockaddr*> user_addr((FlatPtr)msg.msg_name);
|
||||
Userspace<socklen_t*> user_addr_length(msg.msg_name ? (FlatPtr)&user_msg.unsafe_userspace_ptr()->msg_namelen : 0);
|
||||
@ -272,25 +266,20 @@ KResultOr<FlatPtr> Process::sys$recvmsg(int sockfd, Userspace<struct msghdr*> us
|
||||
msg_flags |= MSG_CTRUNC;
|
||||
} else {
|
||||
cmsg_timestamp = { { control_length, SOL_SOCKET, SCM_TIMESTAMP }, timestamp.to_timeval() };
|
||||
if (!copy_to_user(msg.msg_control, &cmsg_timestamp, control_length))
|
||||
return EFAULT;
|
||||
TRY(copy_to_user(msg.msg_control, &cmsg_timestamp, control_length));
|
||||
}
|
||||
if (!copy_to_user(&user_msg.unsafe_userspace_ptr()->msg_controllen, &control_length))
|
||||
return EFAULT;
|
||||
TRY(copy_to_user(&user_msg.unsafe_userspace_ptr()->msg_controllen, &control_length));
|
||||
}
|
||||
|
||||
if (!copy_to_user(&user_msg.unsafe_userspace_ptr()->msg_flags, &msg_flags))
|
||||
return EFAULT;
|
||||
|
||||
TRY(copy_to_user(&user_msg.unsafe_userspace_ptr()->msg_flags, &msg_flags));
|
||||
return result.value();
|
||||
}
|
||||
|
||||
template<bool sockname, typename Params>
|
||||
int Process::get_sock_or_peer_name(const Params& params)
|
||||
KResult Process::get_sock_or_peer_name(const Params& params)
|
||||
{
|
||||
socklen_t addrlen_value;
|
||||
if (!copy_from_user(&addrlen_value, params.addrlen, sizeof(socklen_t)))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(&addrlen_value, params.addrlen, sizeof(socklen_t)));
|
||||
|
||||
if (addrlen_value <= 0)
|
||||
return EINVAL;
|
||||
@ -311,37 +300,31 @@ int Process::get_sock_or_peer_name(const Params& params)
|
||||
socket.get_local_address((sockaddr*)&address_buffer, &addrlen_value);
|
||||
else
|
||||
socket.get_peer_address((sockaddr*)&address_buffer, &addrlen_value);
|
||||
if (!copy_to_user(params.addr, &address_buffer, addrlen_value))
|
||||
return EFAULT;
|
||||
if (!copy_to_user(params.addrlen, &addrlen_value))
|
||||
return EFAULT;
|
||||
return 0;
|
||||
TRY(copy_to_user(params.addr, &address_buffer, addrlen_value));
|
||||
return copy_to_user(params.addrlen, &addrlen_value);
|
||||
}
|
||||
|
||||
KResultOr<FlatPtr> Process::sys$getsockname(Userspace<const Syscall::SC_getsockname_params*> user_params)
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
Syscall::SC_getsockname_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
Syscall::SC_getsockname_params params = {};
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
return get_sock_or_peer_name<true>(params);
|
||||
}
|
||||
|
||||
KResultOr<FlatPtr> Process::sys$getpeername(Userspace<const Syscall::SC_getpeername_params*> user_params)
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
Syscall::SC_getpeername_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
Syscall::SC_getpeername_params params = {};
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
return get_sock_or_peer_name<false>(params);
|
||||
}
|
||||
|
||||
KResultOr<FlatPtr> Process::sys$getsockopt(Userspace<const Syscall::SC_getsockopt_params*> user_params)
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
Syscall::SC_getsockopt_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
Syscall::SC_getsockopt_params params = {};
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
int sockfd = params.sockfd;
|
||||
int level = params.level;
|
||||
@ -350,8 +333,7 @@ KResultOr<FlatPtr> Process::sys$getsockopt(Userspace<const Syscall::SC_getsockop
|
||||
Userspace<socklen_t*> user_value_size((FlatPtr)params.value_size);
|
||||
|
||||
socklen_t value_size;
|
||||
if (!copy_from_user(&value_size, params.value_size, sizeof(socklen_t)))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(&value_size, params.value_size, sizeof(socklen_t)));
|
||||
|
||||
auto description = fds().file_description(sockfd);
|
||||
if (!description)
|
||||
@ -368,8 +350,7 @@ KResultOr<FlatPtr> Process::sys$setsockopt(Userspace<const Syscall::SC_setsockop
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
Syscall::SC_setsockopt_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
Userspace<const void*> user_value((FlatPtr)params.value);
|
||||
auto description = fds().file_description(params.sockfd);
|
||||
if (!description)
|
||||
@ -385,8 +366,7 @@ KResultOr<FlatPtr> Process::sys$socketpair(Userspace<const Syscall::SC_socketpai
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
Syscall::SC_socketpair_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
if (params.domain != AF_LOCAL)
|
||||
return EINVAL;
|
||||
@ -405,7 +385,7 @@ KResultOr<FlatPtr> Process::sys$socketpair(Userspace<const Syscall::SC_socketpai
|
||||
setup_socket_fd(fds[0], pair.description0, params.type);
|
||||
setup_socket_fd(fds[1], pair.description1, params.type);
|
||||
|
||||
if (!copy_to_user(params.sv, fds, sizeof(fds))) {
|
||||
if (copy_to_user(params.sv, fds, sizeof(fds)).is_error()) {
|
||||
// Avoid leaking both file descriptors on error.
|
||||
m_fds[fds[0]] = {};
|
||||
m_fds[fds[1]] = {};
|
||||
|
@ -19,10 +19,8 @@ KResultOr<FlatPtr> Process::sys$fstat(int fd, Userspace<stat*> user_statbuf)
|
||||
if (!description)
|
||||
return EBADF;
|
||||
stat buffer = {};
|
||||
auto result = description->stat(buffer);
|
||||
if (!copy_to_user(user_statbuf, &buffer))
|
||||
return EFAULT;
|
||||
return result;
|
||||
TRY(description->stat(buffer));
|
||||
return copy_to_user(user_statbuf, &buffer);
|
||||
}
|
||||
|
||||
KResultOr<FlatPtr> Process::sys$stat(Userspace<const Syscall::SC_stat_params*> user_params)
|
||||
@ -30,8 +28,7 @@ KResultOr<FlatPtr> Process::sys$stat(Userspace<const Syscall::SC_stat_params*> u
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
REQUIRE_PROMISE(rpath);
|
||||
Syscall::SC_stat_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
auto path = get_syscall_path_argument(params.path);
|
||||
if (path.is_error())
|
||||
return path.error();
|
||||
@ -55,9 +52,7 @@ KResultOr<FlatPtr> Process::sys$stat(Userspace<const Syscall::SC_stat_params*> u
|
||||
auto result = metadata_or_error.value().stat(statbuf);
|
||||
if (result.is_error())
|
||||
return result;
|
||||
if (!copy_to_user(params.statbuf, &statbuf))
|
||||
return EFAULT;
|
||||
return 0;
|
||||
return copy_to_user(params.statbuf, &statbuf);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -62,10 +62,7 @@ KResultOr<FlatPtr> Process::do_statvfs(String path, statvfs* buf)
|
||||
}
|
||||
}
|
||||
|
||||
if (!copy_to_user(buf, &kernelbuf))
|
||||
return EFAULT;
|
||||
|
||||
return 0;
|
||||
return copy_to_user(buf, &kernelbuf);
|
||||
}
|
||||
|
||||
KResultOr<FlatPtr> Process::sys$statvfs(Userspace<const Syscall::SC_statvfs_params*> user_params)
|
||||
@ -74,8 +71,7 @@ KResultOr<FlatPtr> Process::sys$statvfs(Userspace<const Syscall::SC_statvfs_para
|
||||
REQUIRE_PROMISE(rpath);
|
||||
|
||||
Syscall::SC_statvfs_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
auto path = get_syscall_path_argument(params.path);
|
||||
if (path.is_error())
|
||||
return path.error();
|
||||
|
@ -19,8 +19,7 @@ KResultOr<FlatPtr> Process::sys$create_thread(void* (*entry)(void*), Userspace<c
|
||||
REQUIRE_PROMISE(thread);
|
||||
|
||||
Syscall::SC_create_thread_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
unsigned detach_state = params.detach_state;
|
||||
int schedule_priority = params.schedule_priority;
|
||||
@ -151,9 +150,10 @@ KResultOr<FlatPtr> Process::sys$join_thread(pid_t tid, Userspace<void**> exit_va
|
||||
dbgln("join_thread: retrying");
|
||||
}
|
||||
|
||||
if (exit_value && !copy_to_user(exit_value, &joinee_exit_value))
|
||||
return EFAULT;
|
||||
return 0;
|
||||
if (exit_value)
|
||||
TRY(copy_to_user(exit_value, &joinee_exit_value));
|
||||
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
KResultOr<FlatPtr> Process::sys$kill_thread(pid_t tid, int signal)
|
||||
@ -212,17 +212,14 @@ KResultOr<FlatPtr> Process::sys$get_thread_name(pid_t tid, Userspace<char*> buff
|
||||
|
||||
if (thread_name.is_null()) {
|
||||
char null_terminator = '\0';
|
||||
if (!copy_to_user(buffer, &null_terminator, sizeof(null_terminator)))
|
||||
return EFAULT;
|
||||
return 0;
|
||||
TRY(copy_to_user(buffer, &null_terminator, sizeof(null_terminator)));
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
if (thread_name.length() + 1 > buffer_size)
|
||||
return ENAMETOOLONG;
|
||||
|
||||
if (!copy_to_user(buffer, thread_name.characters_without_null_termination(), thread_name.length() + 1))
|
||||
return EFAULT;
|
||||
return 0;
|
||||
return copy_to_user(buffer, thread_name.characters_without_null_termination(), thread_name.length() + 1);
|
||||
}
|
||||
|
||||
KResultOr<FlatPtr> Process::sys$gettid()
|
||||
|
@ -18,9 +18,7 @@ KResultOr<FlatPtr> Process::sys$times(Userspace<tms*> user_times)
|
||||
times.tms_cutime = m_ticks_in_user_for_dead_children;
|
||||
times.tms_cstime = m_ticks_in_kernel_for_dead_children;
|
||||
|
||||
if (!copy_to_user(user_times, ×))
|
||||
return EFAULT;
|
||||
|
||||
TRY(copy_to_user(user_times, ×));
|
||||
return TimeManagement::the().uptime_ms() & 0x7fffffff;
|
||||
}
|
||||
|
||||
|
@ -23,9 +23,7 @@ KResultOr<FlatPtr> Process::sys$ttyname(int fd, Userspace<char*> buffer, size_t
|
||||
auto tty_name = description->tty()->tty_name();
|
||||
if (size < tty_name.length() + 1)
|
||||
return ERANGE;
|
||||
if (!copy_to_user(buffer, tty_name.characters(), tty_name.length() + 1))
|
||||
return EFAULT;
|
||||
return 0;
|
||||
return copy_to_user(buffer, tty_name.characters(), tty_name.length() + 1);
|
||||
}
|
||||
|
||||
KResultOr<FlatPtr> Process::sys$ptsname(int fd, Userspace<char*> buffer, size_t size)
|
||||
@ -41,9 +39,7 @@ KResultOr<FlatPtr> Process::sys$ptsname(int fd, Userspace<char*> buffer, size_t
|
||||
auto pts_name = master_pty->pts_name();
|
||||
if (size < pts_name.length() + 1)
|
||||
return ERANGE;
|
||||
if (!copy_to_user(buffer, pts_name.characters(), pts_name.length() + 1))
|
||||
return EFAULT;
|
||||
return 0;
|
||||
return copy_to_user(buffer, pts_name.characters(), pts_name.length() + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,9 +27,7 @@ KResultOr<FlatPtr> Process::sys$uname(Userspace<utsname*> user_buf)
|
||||
memcpy(buf.nodename, name.characters(), name.length() + 1);
|
||||
});
|
||||
|
||||
if (!copy_to_user(user_buf, &buf))
|
||||
return EFAULT;
|
||||
return 0;
|
||||
return copy_to_user(user_buf, &buf);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,8 +28,7 @@ KResultOr<FlatPtr> Process::sys$unveil(Userspace<const Syscall::SC_unveil_params
|
||||
{
|
||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
|
||||
Syscall::SC_unveil_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
if (!params.path.characters && !params.permissions.characters) {
|
||||
m_veil_state = VeilState::Locked;
|
||||
|
@ -19,8 +19,7 @@ KResultOr<FlatPtr> Process::sys$utime(Userspace<const char*> user_path, size_t p
|
||||
return path.error();
|
||||
utimbuf buf;
|
||||
if (user_buf) {
|
||||
if (!copy_from_user(&buf, user_buf))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(&buf, user_buf));
|
||||
} else {
|
||||
auto now = kgettimeofday().to_truncated_seconds();
|
||||
// Not a bug!
|
||||
|
@ -25,8 +25,7 @@ KResultOr<FlatPtr> Process::sys$waitid(Userspace<const Syscall::SC_waitid_params
|
||||
REQUIRE_PROMISE(proc);
|
||||
|
||||
Syscall::SC_waitid_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return EFAULT;
|
||||
TRY(copy_from_user(¶ms, user_params));
|
||||
|
||||
Variant<Empty, NonnullRefPtr<Process>, NonnullRefPtr<ProcessGroup>> waitee = Empty {};
|
||||
switch (params.idtype) {
|
||||
@ -59,9 +58,7 @@ KResultOr<FlatPtr> Process::sys$waitid(Userspace<const Syscall::SC_waitid_params
|
||||
if (siginfo_or_error.is_error())
|
||||
return siginfo_or_error.error();
|
||||
|
||||
if (!copy_to_user(params.infop, &siginfo_or_error.value()))
|
||||
return EFAULT;
|
||||
return 0;
|
||||
return copy_to_user(params.infop, &siginfo_or_error.value());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -26,8 +26,7 @@ KResultOr<FlatPtr> Process::sys$writev(int fd, Userspace<const struct iovec*> io
|
||||
Vector<iovec, 32> vecs;
|
||||
if (!vecs.try_resize(iov_count))
|
||||
return ENOMEM;
|
||||
if (!copy_n_from_user(vecs.data(), iov, iov_count))
|
||||
return EFAULT;
|
||||
TRY(copy_n_from_user(vecs.data(), iov, iov_count));
|
||||
for (auto& vec : vecs) {
|
||||
total_length += vec.iov_len;
|
||||
if (total_length > NumericLimits<i32>::max())
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user