diff --git a/Kernel/Coredump.cpp b/Kernel/Coredump.cpp index 529d4e3e61b..7d94784be26 100644 --- a/Kernel/Coredump.cpp +++ b/Kernel/Coredump.cpp @@ -182,16 +182,14 @@ ErrorOr Coredump::write_regions() auto* page = region->physical_page(i); uint8_t zero_buffer[PAGE_SIZE] = {}; - Optional src_buffer; - - if (page) { - src_buffer = UserOrKernelBuffer::for_user_buffer(reinterpret_cast((region->vaddr().as_ptr() + (i * PAGE_SIZE))), PAGE_SIZE); - } else { + auto src_buffer = [&]() -> ErrorOr { + if (page) + return UserOrKernelBuffer::for_user_buffer(reinterpret_cast((region->vaddr().as_ptr() + (i * PAGE_SIZE))), PAGE_SIZE); // If the current page is not backed by a physical page, we zero it in the coredump file. // TODO: Do we want to include the contents of pages that have not been faulted-in in the coredump? // (A page may not be backed by a physical page because it has never been faulted in when the process ran). - src_buffer = UserOrKernelBuffer::for_kernel_buffer(zero_buffer); - } + return UserOrKernelBuffer::for_kernel_buffer(zero_buffer); + }(); TRY(m_description->write(src_buffer.value(), PAGE_SIZE)); } } diff --git a/Kernel/Syscalls/get_dir_entries.cpp b/Kernel/Syscalls/get_dir_entries.cpp index 604ab58af19..a3dfd40c914 100644 --- a/Kernel/Syscalls/get_dir_entries.cpp +++ b/Kernel/Syscalls/get_dir_entries.cpp @@ -16,10 +16,8 @@ ErrorOr Process::sys$get_dir_entries(int fd, Userspace user_buff if (user_size > NumericLimits::max()) return EINVAL; auto description = TRY(fds().open_file_description(fd)); - auto buffer = UserOrKernelBuffer::for_user_buffer(user_buffer, static_cast(user_size)); - if (!buffer.has_value()) - return EFAULT; - auto count = TRY(description->get_dir_entries(buffer.value(), user_size)); + auto buffer = TRY(UserOrKernelBuffer::for_user_buffer(user_buffer, static_cast(user_size))); + auto count = TRY(description->get_dir_entries(buffer, user_size)); return count; } diff --git a/Kernel/Syscalls/getrandom.cpp b/Kernel/Syscalls/getrandom.cpp index 21e9efb848d..ee1e6d4913a 100644 --- a/Kernel/Syscalls/getrandom.cpp +++ b/Kernel/Syscalls/getrandom.cpp @@ -20,11 +20,9 @@ ErrorOr Process::sys$getrandom(Userspace buffer, size_t buffer_s if (buffer_size > NumericLimits::max()) return EINVAL; - auto data_buffer = UserOrKernelBuffer::for_user_buffer(buffer, buffer_size); - if (!data_buffer.has_value()) - return EFAULT; + auto data_buffer = TRY(UserOrKernelBuffer::for_user_buffer(buffer, buffer_size)); - return TRY(data_buffer.value().write_buffered<1024>(buffer_size, [&](Bytes bytes) { + return TRY(data_buffer.write_buffered<1024>(buffer_size, [&](Bytes bytes) { get_good_random_bytes(bytes); return bytes.size(); })); diff --git a/Kernel/Syscalls/read.cpp b/Kernel/Syscalls/read.cpp index a0012859252..2de85e5bbfb 100644 --- a/Kernel/Syscalls/read.cpp +++ b/Kernel/Syscalls/read.cpp @@ -63,10 +63,8 @@ ErrorOr Process::sys$readv(int fd, Userspace iov, int nread = 0; for (auto& vec : vecs) { TRY(check_blocked_read(description)); - auto buffer = UserOrKernelBuffer::for_user_buffer((u8*)vec.iov_base, vec.iov_len); - if (!buffer.has_value()) - return EFAULT; - auto nread_here = TRY(description->read(buffer.value(), vec.iov_len)); + auto buffer = TRY(UserOrKernelBuffer::for_user_buffer((u8*)vec.iov_base, vec.iov_len)); + auto nread_here = TRY(description->read(buffer, vec.iov_len)); nread += nread_here; } @@ -84,10 +82,8 @@ ErrorOr Process::sys$read(int fd, Userspace buffer, size_t size) dbgln_if(IO_DEBUG, "sys$read({}, {}, {})", fd, buffer.ptr(), size); auto description = TRY(open_readable_file_description(fds(), fd)); TRY(check_blocked_read(description)); - auto user_buffer = UserOrKernelBuffer::for_user_buffer(buffer, size); - if (!user_buffer.has_value()) - return EFAULT; - return TRY(description->read(user_buffer.value(), size)); + auto user_buffer = TRY(UserOrKernelBuffer::for_user_buffer(buffer, size)); + return TRY(description->read(user_buffer, size)); } ErrorOr Process::sys$pread(int fd, Userspace buffer, size_t size, Userspace userspace_offset) @@ -107,10 +103,8 @@ ErrorOr Process::sys$pread(int fd, Userspace buffer, size_t size, if (!description->file().is_seekable()) return EINVAL; TRY(check_blocked_read(description)); - auto user_buffer = UserOrKernelBuffer::for_user_buffer(buffer, size); - if (!user_buffer.has_value()) - return EFAULT; - return TRY(description->read(user_buffer.value(), offset, size)); + auto user_buffer = TRY(UserOrKernelBuffer::for_user_buffer(buffer, size)); + return TRY(description->read(user_buffer, offset, size)); } } diff --git a/Kernel/Syscalls/socket.cpp b/Kernel/Syscalls/socket.cpp index 74a2a1bf963..5f0a40a43d2 100644 --- a/Kernel/Syscalls/socket.cpp +++ b/Kernel/Syscalls/socket.cpp @@ -182,10 +182,8 @@ ErrorOr Process::sys$sendmsg(int sockfd, Userspacesocket(); if (socket.is_shut_down_for_writing()) return EPIPE; - auto data_buffer = UserOrKernelBuffer::for_user_buffer((u8*)iovs[0].iov_base, iovs[0].iov_len); - if (!data_buffer.has_value()) - return EFAULT; - auto bytes_sent = TRY(socket.sendto(*description, data_buffer.value(), iovs[0].iov_len, flags, user_addr, addr_length)); + auto data_buffer = TRY(UserOrKernelBuffer::for_user_buffer((u8*)iovs[0].iov_base, iovs[0].iov_len)); + auto bytes_sent = TRY(socket.sendto(*description, data_buffer, iovs[0].iov_len, flags, user_addr, addr_length)); return bytes_sent; } @@ -218,11 +216,9 @@ ErrorOr Process::sys$recvmsg(int sockfd, Userspace user if (flags & MSG_DONTWAIT) description->set_blocking(false); - auto data_buffer = UserOrKernelBuffer::for_user_buffer((u8*)iovs[0].iov_base, iovs[0].iov_len); - if (!data_buffer.has_value()) - return EFAULT; + auto data_buffer = TRY(UserOrKernelBuffer::for_user_buffer((u8*)iovs[0].iov_base, iovs[0].iov_len)); Time timestamp {}; - auto result = socket.recvfrom(*description, data_buffer.value(), iovs[0].iov_len, flags, user_addr, user_addr_length, timestamp); + auto result = socket.recvfrom(*description, data_buffer, iovs[0].iov_len, flags, user_addr, user_addr_length, timestamp); if (flags & MSG_DONTWAIT) description->set_blocking(original_blocking); diff --git a/Kernel/Syscalls/write.cpp b/Kernel/Syscalls/write.cpp index 09d4c40cfb0..d056df3b6b7 100644 --- a/Kernel/Syscalls/write.cpp +++ b/Kernel/Syscalls/write.cpp @@ -38,10 +38,8 @@ ErrorOr Process::sys$writev(int fd, Userspace iov, int nwritten = 0; for (auto& vec : vecs) { - auto buffer = UserOrKernelBuffer::for_user_buffer((u8*)vec.iov_base, vec.iov_len); - if (!buffer.has_value()) - return EFAULT; - auto result = do_write(*description, buffer.value(), vec.iov_len); + auto buffer = TRY(UserOrKernelBuffer::for_user_buffer((u8*)vec.iov_base, vec.iov_len)); + auto result = do_write(*description, buffer, vec.iov_len); if (result.is_error()) { if (nwritten == 0) return result.release_error(); @@ -104,10 +102,8 @@ ErrorOr Process::sys$write(int fd, Userspace data, size_t si if (!description->is_writable()) return EBADF; - auto buffer = UserOrKernelBuffer::for_user_buffer(data, static_cast(size)); - if (!buffer.has_value()) - return EFAULT; - return do_write(*description, buffer.value(), size); + auto buffer = TRY(UserOrKernelBuffer::for_user_buffer(data, static_cast(size))); + return do_write(*description, buffer, size); } } diff --git a/Kernel/UserOrKernelBuffer.h b/Kernel/UserOrKernelBuffer.h index 11ffaf8dac0..bebd512f3f1 100644 --- a/Kernel/UserOrKernelBuffer.h +++ b/Kernel/UserOrKernelBuffer.h @@ -26,18 +26,18 @@ public: return UserOrKernelBuffer(kernel_buffer); } - static Optional for_user_buffer(u8* user_buffer, size_t size) + static ErrorOr for_user_buffer(u8* user_buffer, size_t size) { if (user_buffer && !Memory::is_user_range(VirtualAddress(user_buffer), size)) - return {}; + return Error::from_errno(EFAULT); return UserOrKernelBuffer(user_buffer); } template - static Optional for_user_buffer(UserspaceType userspace, size_t size) + static ErrorOr for_user_buffer(UserspaceType userspace, size_t size) { if (!Memory::is_user_range(VirtualAddress(userspace.unsafe_userspace_ptr()), size)) - return {}; + return Error::from_errno(EFAULT); return UserOrKernelBuffer(const_cast((const u8*)userspace.unsafe_userspace_ptr())); }