From: Tomas Mraz Date: Tue, 10 Sep 2024 17:11:56 +0000 (+0200) Subject: ossl_rio_notifier_init(): Add error messages X-Git-Tag: openssl-3.5.0-alpha1~336 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0e470373ad683cb523685931461f3076b7c3e9d5;p=thirdparty%2Fopenssl.git ossl_rio_notifier_init(): Add error messages Reviewed-by: Matt Caswell Reviewed-by: Saša Nedvědický (Merged from https://github.com/openssl/openssl/pull/25416) --- diff --git a/ssl/rio/rio_notifier.c b/ssl/rio/rio_notifier.c index 84d64ddb74c..9e6128893d1 100644 --- a/ssl/rio/rio_notifier.c +++ b/ssl/rio/rio_notifier.c @@ -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 +#include /* * 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];