]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
ossl_rio_notifier_init(): Add error messages
authorTomas Mraz <tomas@openssl.org>
Tue, 10 Sep 2024 17:11:56 +0000 (19:11 +0200)
committerNeil Horman <nhorman@openssl.org>
Sat, 11 Jan 2025 21:02:29 +0000 (16:02 -0500)
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/25416)

ssl/rio/rio_notifier.c

index 84d64ddb74cd423bbb8775aceb5a3418e68f9287..9e6128893d1a81f5c6fdf4d2e6491940ce68e6b3 100644 (file)
@@ -1,6 +1,16 @@
+/*
+ * Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
 #include "internal/rio_notifier.h"
 #include "internal/sockets.h"
 #include <openssl/bio.h>
+#include <openssl/err.h>
 
 /*
  * Sets a socket as close-on-exec, except that this is a no-op if we are certain
@@ -32,13 +42,20 @@ static int create_socket(int domain, int socktype, int protocol)
      */
     fd = (int)WSASocketA(domain, socktype, protocol, NULL, 0,
                          WSA_FLAG_NO_HANDLE_INHERIT);
-    if (fd == INVALID_SOCKET)
-        return -1;
+    if (fd == INVALID_SOCKET) {
+        int err = get_last_socket_error();
+
+        ERR_raise_data(ERR_LIB_SYS, err,
+                       "calling WSASocketA() = %d", err);
+        return INVALID_SOCKET;
+    }
 
     /* Prevent interference with the socket from other processes on Windows. */
     if (setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (void *)&on, sizeof(on)) < 0) {
+        ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
+                       "calling setsockopt()");
         BIO_closesocket(fd);
-        return -1;
+        return INVALID_SOCKET;
     }
 
 #else
@@ -47,16 +64,21 @@ static int create_socket(int domain, int socktype, int protocol)
 # endif
 
     fd = BIO_socket(domain, socktype, protocol, 0);
-    if (fd == INVALID_SOCKET)
-        return -1;
+    if (fd == INVALID_SOCKET) {
+        ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+                       "calling BIO_socket()");
+        return INVALID_SOCKET;
+    }
 
     /*
      * Make socket close-on-exec unless this was already done above at socket
      * creation time.
      */
     if (!set_cloexec(fd)) {
+        ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+                       "calling set_cloexec()");
         BIO_closesocket(fd);
-        return -1;
+        return INVALID_SOCKET;
     }
 #endif
 
@@ -80,55 +102,82 @@ int ossl_rio_notifier_init(RIO_NOTIFIER *nfy)
 
     /* Create a close-on-exec socket. */
     lfd = create_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-    if (lfd == INVALID_SOCKET)
+    if (lfd == INVALID_SOCKET) {
+        ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+                       "calling create_socket()");
         return 0;
+    }
 
     /* Bind the socket to a random loopback port. */
     sa.sin_family       = AF_INET;
     sa.sin_addr.s_addr  = htonl(INADDR_LOOPBACK);
     rc = bind(lfd, (const struct sockaddr *)&sa, sizeof(sa));
-    if (rc < 0)
+    if (rc < 0) {
+        ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+                       "calling bind()");
         goto err;
+    }
 
     /* Determine what random port was allocated. */
     rc = getsockname(lfd, (struct sockaddr *)&sa, &sa_len);
-    if (rc < 0)
+    if (rc < 0) {
+        ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+                       "calling getsockname()");
         goto err;
+    }
 
     /* Start listening. */
     rc = listen(lfd, 1);
-    if (rc < 0)
+    if (rc < 0) {
+        ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+                       "calling listen()");
         goto err;
+    }
 
     /* Create another socket to connect to the listener. */
     wfd = create_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-    if (wfd < 0)
+    if (wfd == INVALID_SOCKET) {
+        ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+                       "calling create_socket()");
         goto err;
+    }
 
     /*
      * Disable Nagle's algorithm on the writer so that wakeups happen
      * immediately.
      */
-    if (!BIO_set_tcp_ndelay(wfd, 1))
+    if (!BIO_set_tcp_ndelay(wfd, 1)) {
+        ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+                       "calling BIO_set_tcp_ndelay()");
         goto err;
+    }
 
     /*
      * Connect the writer to the listener.
      */
     rc = connect(wfd, (struct sockaddr *)&sa, sizeof(sa));
-    if (rc < 0)
+    if (rc < 0) {
+        ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+                       "calling connect()");
         goto err;
+    }
 
     /*
      * The connection accepted from the listener is the read side.
      */
     rfd = accept(lfd, (struct sockaddr *)&accept_sa, &accept_sa_len);
-    if (rfd < 0)
+    if (rfd == INVALID_SOCKET) {
+        ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+                       "calling accept()");
         goto err;
+    }
 
     rc = getsockname(wfd, (struct sockaddr *)&sa, &sa_len);
-    if (rc < 0)
+    if (rc < 0) {
+        ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+                       "calling getsockname()");
         goto err;
+    }
 
     /* Close the listener, which we don't need anymore. */
     BIO_closesocket(lfd);
@@ -138,26 +187,35 @@ int ossl_rio_notifier_init(RIO_NOTIFIER *nfy)
      * Sanity check - ensure someone else didn't connect to our listener during
      * the brief window of possibility above.
      */
-    if (accept_sa.sin_family != AF_INET || accept_sa.sin_port != sa.sin_port)
+    if (accept_sa.sin_family != AF_INET || accept_sa.sin_port != sa.sin_port) {
+        ERR_raise_data(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR,
+                       "connected address differs from accepted address");
         goto err;
+    }
 
     /* Make both sides of the connection non-blocking. */
-    if (!BIO_socket_nbio(rfd, 1))
+    if (!BIO_socket_nbio(rfd, 1)) {
+        ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+                       "calling BIO_socket_nbio()");
         goto err;
+    }
 
-    if (!BIO_socket_nbio(wfd, 1))
+    if (!BIO_socket_nbio(wfd, 1)) {
+        ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+                       "calling BIO_socket_nbio()");
         goto err;
+    }
 
     nfy->rfd = rfd;
     nfy->wfd = wfd;
     return 1;
 
 err:
-    if (lfd >= 0)
+    if (lfd != INVALID_SOCKET)
         BIO_closesocket(lfd);
-    if (wfd >= 0)
+    if (wfd != INVALID_SOCKET)
         BIO_closesocket(wfd);
-    if (rfd >= 0)
+    if (rfd != INVALID_SOCKET)
         BIO_closesocket(rfd);
     return 0;
 }
@@ -179,19 +237,31 @@ int ossl_rio_notifier_init(RIO_NOTIFIER *nfy)
     domain = AF_UNIX;
 #endif
 
-    if (socketpair(domain, type, 0, fds) < 0)
+    if (socketpair(domain, type, 0, fds) < 0) {
+        ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+                       "calling socketpair()");
         return 0;
+    }
 
-    if (!set_cloexec(fds[0]) || !set_cloexec(fds[1]))
+    if (!set_cloexec(fds[0]) || !set_cloexec(fds[1])) {
+        ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+                       "calling set_cloexec()");
         goto err;
+    }
 
 #if !defined(SOCK_NONBLOCK)
-    if (!BIO_socket_nbio(fds[0], 1) || !BIO_socket_nbio(fds[1], 1))
+    if (!BIO_socket_nbio(fds[0], 1) || !BIO_socket_nbio(fds[1], 1)) {
+        ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+                       "calling BIO_socket_nbio()");
         goto err;
+    }
 #endif
 
-    if (domain == AF_INET && !BIO_set_tcp_ndelay(fds[1], 1))
+    if (domain == AF_INET && !BIO_set_tcp_ndelay(fds[1], 1)) {
+        ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+                       "calling BIO_set_tcp_ndelay()");
         goto err;
+    }
 
     nfy->rfd = fds[0];
     nfy->wfd = fds[1];