Commit 2bfc6d14d5

lithdew <kenta@lithdew.net>
2021-04-01 22:28:25
os/linux: return error on EALREADY for connect() and getsockoptError()
When a connected socket file descriptor on Linux is re-acquired after being closed, through fuzz testing, it appears that a subsequent attempt to establish a connection with the file descriptor causes EALREADY to be reported. Instead of panicking, choose to return error.ConnectionPending to allow for users to handle this fairly rare case.
1 parent 83a2665
Changed files (1)
lib
std
lib/std/os.zig
@@ -3254,6 +3254,9 @@ pub const ConnectError = error{
 
     /// Connection was reset by peer before connect could complete.
     ConnectionResetByPeer,
+
+    /// Socket is non-blocking and already has a pending connection in progress.
+    ConnectionPending,
 } || UnexpectedError;
 
 /// Initiate a connection on a socket.
@@ -3294,7 +3297,7 @@ pub fn connect(sock: socket_t, sock_addr: *const sockaddr, len: socklen_t) Conne
             EADDRNOTAVAIL => return error.AddressNotAvailable,
             EAFNOSUPPORT => return error.AddressFamilyNotSupported,
             EAGAIN, EINPROGRESS => return error.WouldBlock,
-            EALREADY => unreachable, // The socket is nonblocking and a previous connection attempt has not yet been completed.
+            EALREADY => return error.ConnectionPending,
             EBADF => unreachable, // sockfd is not a valid open file descriptor.
             ECONNREFUSED => return error.ConnectionRefused,
             ECONNRESET => return error.ConnectionResetByPeer,
@@ -3325,7 +3328,7 @@ pub fn getsockoptError(sockfd: fd_t) ConnectError!void {
             EADDRNOTAVAIL => return error.AddressNotAvailable,
             EAFNOSUPPORT => return error.AddressFamilyNotSupported,
             EAGAIN => return error.SystemResources,
-            EALREADY => unreachable, // The socket is nonblocking and a previous connection attempt has not yet been completed.
+            EALREADY => return error.ConnectionPending,
             EBADF => unreachable, // sockfd is not a valid open file descriptor.
             ECONNREFUSED => return error.ConnectionRefused,
             EFAULT => unreachable, // The socket structure address is outside the user's address space.