From e48cbf3c8c22ba245fc862f73c51a1180cfd0e9e Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 20 Mar 2019 02:38:36 +0100 Subject: [PATCH] Kernel: connect() should fail with EISCONN for already-connected sockets. Also make sure to reset the socket role if Socket::connect() fails. --- Kernel/FileDescriptor.h | 1 + Kernel/Process.cpp | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Kernel/FileDescriptor.h b/Kernel/FileDescriptor.h index 0b890c04d2..4fa5aa6dae 100644 --- a/Kernel/FileDescriptor.h +++ b/Kernel/FileDescriptor.h @@ -88,6 +88,7 @@ public: void set_original_inode(Badge, Retained&& inode) { m_inode = move(inode); } + SocketRole socket_role() const { return m_socket_role; } void set_socket_role(SocketRole); private: diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index a7051c88cb..b542606fcb 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -2502,11 +2502,15 @@ int Process::sys$connect(int sockfd, const sockaddr* address, socklen_t address_ return -EBADF; if (!descriptor->is_socket()) return -ENOTSOCK; + if (descriptor->socket_role() == SocketRole::Connected) + return -EISCONN; auto& socket = *descriptor->socket(); descriptor->set_socket_role(SocketRole::Connecting); auto result = socket.connect(address, address_size); - if (result.is_error()) + if (result.is_error()) { + descriptor->set_socket_role(SocketRole::None); return result; + } descriptor->set_socket_role(SocketRole::Connected); return 0; }