diff options
author | Andreas Kling <kling@serenityos.org> | 2021-09-07 15:36:39 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-09-07 15:36:39 +0200 |
commit | b300f9aa2fd11796e63b5029008b33a1ae735928 (patch) | |
tree | 31d96f52a7733dc7de131eea9b096c58a411523f /Kernel | |
parent | 250b52d6e5ef4b57048ef7f52a02ebb2fb87780b (diff) | |
download | serenity-b300f9aa2fd11796e63b5029008b33a1ae735928.zip |
Kernel: Convert KBuffer::copy() => KBuffer::try_copy()
This was a weird KBuffer API that assumed failure was impossible.
This patch converts it to a modern KResultOr<NonnullOwnPtr<KBuffer>> API
and updates the two clients to the new style.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/KBuffer.h | 7 | ||||
-rw-r--r-- | Kernel/Module.h | 2 | ||||
-rw-r--r-- | Kernel/Net/IPv4Socket.cpp | 52 | ||||
-rw-r--r-- | Kernel/Net/IPv4Socket.h | 2 | ||||
-rw-r--r-- | Kernel/Syscalls/module.cpp | 14 |
5 files changed, 49 insertions, 28 deletions
diff --git a/Kernel/KBuffer.h b/Kernel/KBuffer.h index 9091a9578e..a70275fe37 100644 --- a/Kernel/KBuffer.h +++ b/Kernel/KBuffer.h @@ -122,9 +122,12 @@ public: return adopt_nonnull_own_or_enomem(new (nothrow) KBuffer(impl.release_nonnull())); } - [[nodiscard]] static KBuffer copy(const void* data, size_t size, Memory::Region::Access access = Memory::Region::Access::ReadWrite, StringView name = "KBuffer") + static KResultOr<NonnullOwnPtr<KBuffer>> try_copy(const void* data, size_t size, Memory::Region::Access access = Memory::Region::Access::ReadWrite, StringView name = "KBuffer") { - return KBuffer(KBufferImpl::copy(data, size, access, name)); + auto impl = KBufferImpl::copy(data, size, access, name); + if (!impl) + return ENOMEM; + return adopt_nonnull_own_or_enomem(new (nothrow) KBuffer(impl.release_nonnull())); } [[nodiscard]] bool is_null() const { return !m_impl; } diff --git a/Kernel/Module.h b/Kernel/Module.h index 812a1070b2..55893a620e 100644 --- a/Kernel/Module.h +++ b/Kernel/Module.h @@ -17,7 +17,7 @@ typedef void* (*ModuleFiniPtr)(); struct Module { String name; - Vector<KBuffer> sections; + NonnullOwnPtrVector<KBuffer> sections; ModuleInitPtr module_init { nullptr }; ModuleFiniPtr module_fini { nullptr }; diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index efec7e4ae5..bf155ed6f1 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -284,7 +284,8 @@ KResultOr<size_t> IPv4Socket::receive_byte_buffered(OpenFileDescription& descrip KResultOr<size_t> IPv4Socket::receive_packet_buffered(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*> addr, Userspace<socklen_t*> addr_length, Time& packet_timestamp) { MutexLocker locker(mutex()); - ReceivedPacket packet; + ReceivedPacket taken_packet; + ReceivedPacket* packet { nullptr }; { if (m_receive_queue.is_empty()) { // FIXME: Shouldn't this return ENOTCONN instead of EOF? @@ -296,20 +297,22 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(OpenFileDescription& descr } if (!m_receive_queue.is_empty()) { - if (flags & MSG_PEEK) - packet = m_receive_queue.first(); - else - packet = m_receive_queue.take_first(); + if (flags & MSG_PEEK) { + packet = &m_receive_queue.first(); + } else { + taken_packet = m_receive_queue.take_first(); + packet = &taken_packet; + } set_can_read(!m_receive_queue.is_empty()); dbgln_if(IPV4_SOCKET_DEBUG, "IPv4Socket({}): recvfrom without blocking {} bytes, packets in queue: {}", this, - packet.data.value().size(), + packet->data->size(), m_receive_queue.size()); } } - if (!packet.data.has_value()) { + if (!packet->data) { if (protocol_is_disconnected()) { dbgln("IPv4Socket({}) is protocol-disconnected, returning 0 in recvfrom!", this); return 0; @@ -330,28 +333,30 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(OpenFileDescription& descr VERIFY(m_can_read); VERIFY(!m_receive_queue.is_empty()); - if (flags & MSG_PEEK) - packet = m_receive_queue.first(); - else - packet = m_receive_queue.take_first(); + if (flags & MSG_PEEK) { + packet = &m_receive_queue.first(); + } else { + taken_packet = m_receive_queue.take_first(); + packet = &taken_packet; + } set_can_read(!m_receive_queue.is_empty()); dbgln_if(IPV4_SOCKET_DEBUG, "IPv4Socket({}): recvfrom with blocking {} bytes, packets in queue: {}", this, - packet.data.value().size(), + packet->data->size(), m_receive_queue.size()); } - VERIFY(packet.data.has_value()); + VERIFY(packet->data); - packet_timestamp = packet.timestamp; + packet_timestamp = packet->timestamp; if (addr) { - dbgln_if(IPV4_SOCKET_DEBUG, "Incoming packet is from: {}:{}", packet.peer_address, packet.peer_port); + dbgln_if(IPV4_SOCKET_DEBUG, "Incoming packet is from: {}:{}", packet->peer_address, packet->peer_port); sockaddr_in out_addr {}; - memcpy(&out_addr.sin_addr, &packet.peer_address, sizeof(IPv4Address)); - out_addr.sin_port = htons(packet.peer_port); + memcpy(&out_addr.sin_addr, &packet->peer_address, sizeof(IPv4Address)); + out_addr.sin_port = htons(packet->peer_port); out_addr.sin_family = AF_INET; Userspace<sockaddr_in*> dest_addr = addr.ptr(); SOCKET_TRY(copy_to_user(dest_addr, &out_addr)); @@ -362,12 +367,12 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(OpenFileDescription& descr } if (type() == SOCK_RAW) { - size_t bytes_written = min(packet.data.value().size(), buffer_length); - SOCKET_TRY(buffer.write(packet.data.value().data(), bytes_written)); + size_t bytes_written = min(packet->data->size(), buffer_length); + SOCKET_TRY(buffer.write(packet->data->data(), bytes_written)); return bytes_written; } - return protocol_receive(ReadonlyBytes { packet.data.value().data(), packet.data.value().size() }, buffer, buffer_length, flags); + return protocol_receive(ReadonlyBytes { packet->data->data(), packet->data->size() }, buffer, buffer_length, flags); } KResultOr<size_t> IPv4Socket::recvfrom(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*> user_addr, Userspace<socklen_t*> user_addr_length, Time& packet_timestamp) @@ -421,7 +426,12 @@ bool IPv4Socket::did_receive(const IPv4Address& source_address, u16 source_port, dbgln("IPv4Socket({}): did_receive refusing packet since queue is full.", this); return false; } - m_receive_queue.append({ source_address, source_port, packet_timestamp, KBuffer::copy(packet.data(), packet.size()) }); + auto data_or_error = KBuffer::try_copy(packet.data(), packet.size()); + if (data_or_error.is_error()) { + dbgln("IPv4Socket: did_receive unable to allocate storage for incoming packet."); + return false; + } + m_receive_queue.append({ source_address, source_port, packet_timestamp, data_or_error.release_value() }); set_can_read(true); } m_bytes_received += packet_size; diff --git a/Kernel/Net/IPv4Socket.h b/Kernel/Net/IPv4Socket.h index 3ec3521acc..d416305601 100644 --- a/Kernel/Net/IPv4Socket.h +++ b/Kernel/Net/IPv4Socket.h @@ -110,7 +110,7 @@ private: IPv4Address peer_address; u16 peer_port; Time timestamp; - Optional<KBuffer> data; + OwnPtr<KBuffer> data; }; SinglyLinkedListWithCount<ReceivedPacket> m_receive_queue; diff --git a/Kernel/Syscalls/module.cpp b/Kernel/Syscalls/module.cpp index fe7066505b..b7a05b18e3 100644 --- a/Kernel/Syscalls/module.cpp +++ b/Kernel/Syscalls/module.cpp @@ -41,13 +41,21 @@ KResultOr<FlatPtr> Process::sys$module_load(Userspace<const char*> user_path, si if (!module) return ENOMEM; + KResult section_loading_result = KSuccess; elf_image->for_each_section_of_type(SHT_PROGBITS, [&](const ELF::Image::Section& section) { - if (!section.size()) + if (!section.size() || !section_loading_result.is_error()) + return; + auto section_storage_or_error = KBuffer::try_copy(section.raw_data(), section.size(), Memory::Region::Access::ReadWriteExecute); + if (section_storage_or_error.is_error()) { + section_loading_result = section_storage_or_error.error(); return; - auto section_storage = KBuffer::copy(section.raw_data(), section.size(), Memory::Region::Access::ReadWriteExecute); - section_storage_by_name.set(section.name(), section_storage.data()); + } + auto section_storage = section_storage_or_error.release_value(); + section_storage_by_name.set(section.name(), section_storage->data()); module->sections.append(move(section_storage)); }); + if (section_loading_result.is_error()) + return section_loading_result; bool missing_symbols = false; |