summaryrefslogtreecommitdiff
path: root/Kernel/Net
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-12-23 20:24:00 +0100
committerAndreas Kling <kling@serenityos.org>2020-12-23 20:25:29 +0100
commitc6a0694f50f239dd1f3f4ab6cc876a160a66f90f (patch)
tree7f474628775b1bb88ccc39fc4c949ea1c09f8b88 /Kernel/Net
parent80ae407d739074fd07b72ae6014dffef011869b9 (diff)
downloadserenity-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.cpp33
-rw-r--r--Kernel/Net/LocalSocket.h4
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&);