diff options
author | Andreas Kling <kling@serenityos.org> | 2020-12-23 20:24:00 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-12-23 20:25:29 +0100 |
commit | c6a0694f50f239dd1f3f4ab6cc876a160a66f90f (patch) | |
tree | 7f474628775b1bb88ccc39fc4c949ea1c09f8b88 /Kernel/Net | |
parent | 80ae407d739074fd07b72ae6014dffef011869b9 (diff) | |
download | serenity-c6a0694f50f239dd1f3f4ab6cc876a160a66f90f.zip |
Kernel: Don't assert when reading from a listening-mode local socket
Instead just fail with EINVAL as a listening socket is never suitable
for reading from.
Fixes #4511.
Diffstat (limited to 'Kernel/Net')
-rw-r--r-- | Kernel/Net/LocalSocket.cpp | 33 | ||||
-rw-r--r-- | Kernel/Net/LocalSocket.h | 4 |
2 files changed, 21 insertions, 16 deletions
diff --git a/Kernel/Net/LocalSocket.cpp b/Kernel/Net/LocalSocket.cpp index 345cb7db05..b628d2dc6c 100644 --- a/Kernel/Net/LocalSocket.cpp +++ b/Kernel/Net/LocalSocket.cpp @@ -286,37 +286,42 @@ KResultOr<size_t> LocalSocket::sendto(FileDescription& description, const UserOr { if (!has_attached_peer(description)) return KResult(-EPIPE); - ssize_t nwritten = send_buffer_for(description).write(data, data_size); + auto* socket_buffer = send_buffer_for(description); + if (!socket_buffer) + return KResult(-EINVAL); + ssize_t nwritten = socket_buffer->write(data, data_size); if (nwritten > 0) Thread::current()->did_unix_socket_write(nwritten); return nwritten; } -DoubleBuffer& LocalSocket::receive_buffer_for(FileDescription& description) +DoubleBuffer* LocalSocket::receive_buffer_for(FileDescription& description) { auto role = this->role(description); if (role == Role::Accepted) - return m_for_server; + return &m_for_server; if (role == Role::Connected) - return m_for_client; - ASSERT_NOT_REACHED(); + return &m_for_client; + return nullptr; } -DoubleBuffer& LocalSocket::send_buffer_for(FileDescription& description) +DoubleBuffer* LocalSocket::send_buffer_for(FileDescription& description) { auto role = this->role(description); if (role == Role::Connected) - return m_for_server; + return &m_for_server; if (role == Role::Accepted) - return m_for_client; - ASSERT_NOT_REACHED(); + return &m_for_client; + return nullptr; } KResultOr<size_t> LocalSocket::recvfrom(FileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_size, int, Userspace<sockaddr*>, Userspace<socklen_t*>, timeval&) { - auto& buffer_for_me = receive_buffer_for(description); + auto* socket_buffer = receive_buffer_for(description); + if (!socket_buffer) + return KResult(-EINVAL); if (!description.is_blocking()) { - if (buffer_for_me.is_empty()) { + if (socket_buffer->is_empty()) { if (!has_attached_peer(description)) return 0; return KResult(-EAGAIN); @@ -326,10 +331,10 @@ KResultOr<size_t> LocalSocket::recvfrom(FileDescription& description, UserOrKern if (Thread::current()->block<Thread::ReadBlocker>(nullptr, description, unblock_flags).was_interrupted()) return KResult(-EINTR); } - if (!has_attached_peer(description) && buffer_for_me.is_empty()) + if (!has_attached_peer(description) && socket_buffer->is_empty()) return 0; - ASSERT(!buffer_for_me.is_empty()); - int nread = buffer_for_me.read(buffer, buffer_size); + ASSERT(!socket_buffer->is_empty()); + auto nread = socket_buffer->read(buffer, buffer_size); if (nread > 0) Thread::current()->did_unix_socket_read(nread); return nread; diff --git a/Kernel/Net/LocalSocket.h b/Kernel/Net/LocalSocket.h index 3b9395d1a1..f0025cdb14 100644 --- a/Kernel/Net/LocalSocket.h +++ b/Kernel/Net/LocalSocket.h @@ -72,8 +72,8 @@ private: virtual bool is_local() const override { return true; } bool has_attached_peer(const FileDescription&) const; static Lockable<InlineLinkedList<LocalSocket>>& all_sockets(); - DoubleBuffer& receive_buffer_for(FileDescription&); - DoubleBuffer& send_buffer_for(FileDescription&); + DoubleBuffer* receive_buffer_for(FileDescription&); + DoubleBuffer* send_buffer_for(FileDescription&); NonnullRefPtrVector<FileDescription>& sendfd_queue_for(const FileDescription&); NonnullRefPtrVector<FileDescription>& recvfd_queue_for(const FileDescription&); |