From 8f380c08817b92925f87a57fe27559d34d061d42 Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Fri, 20 Mar 2026 19:55:11 +0000 Subject: [PATCH 1/2] =?UTF-8?q?Fix=20wolfip=20coverity=201683231,=20168321?= =?UTF-8?q?3,=201686341,=201683243,=201683239,=201683212,=201683230,=20168?= =?UTF-8?q?3217,=201683242=20(=C3=973=20locations),=201683226,=201683236,?= =?UTF-8?q?=201683238?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/port/posix/bsd_socket.c | 46 +++++++++++++++++----------------- src/test/ipfilter_logger.c | 2 +- src/test/test_eventloop_tun.c | 14 ++++++++--- src/test/test_ttl_expired.c | 11 +++++++- src/test/unit/unit_tests_api.c | 1 + src/wolfip.c | 6 ++++- 6 files changed, 51 insertions(+), 29 deletions(-) diff --git a/src/port/posix/bsd_socket.c b/src/port/posix/bsd_socket.c index da3bde63..b0870a5f 100644 --- a/src/port/posix/bsd_socket.c +++ b/src/port/posix/bsd_socket.c @@ -899,7 +899,7 @@ int wolfIP_sock_recvmsg(struct wolfIP *ipstack, int sockfd, struct msghdr *msg, socklen_t addrlen = 0; size_t total_len = 0; int ret; - uint8_t stack_buf[WOLFIP_IOV_STACK_BUF]; + uint8_t stack_buf[WOLFIP_IOV_STACK_BUF] = {0}; uint8_t *heap_buf = NULL; uint8_t *buf = NULL; struct pollfd pfd; @@ -1274,6 +1274,7 @@ static int wolfip_accept_common(int sockfd, struct sockaddr *addr, socklen_t *ad return -1; } wolfip_drain_pipe_locked(entry); + want_nonblock = wolfip_fd_is_nonblock(sockfd); } } while (internal_ret == -EAGAIN); if (internal_ret < 0) { @@ -1450,12 +1451,9 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct } if (ret == -EAGAIN) { if (nonblock) { - if (sent == 0) { - errno = EAGAIN; - pthread_mutex_unlock(&wolfIP_mutex); - return -1; - } - break; + errno = EAGAIN; + pthread_mutex_unlock(&wolfIP_mutex); + return -1; } if (entry) { wait_ret = wolfip_wait_for_event_locked(entry, POLLOUT, entry->snd_timeout_ms); @@ -1472,7 +1470,7 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct if (internal_fd < 0) { pthread_mutex_unlock(&wolfIP_mutex); errno = EBADF; - return (sent == 0) ? -1 : (ssize_t)sent; + return -1; } } continue; @@ -1521,12 +1519,9 @@ ssize_t send(int sockfd, const void *buf, size_t len, int flags) { } if (ret == -EAGAIN) { if (nonblock) { - if (sent == 0) { - errno = EAGAIN; - pthread_mutex_unlock(&wolfIP_mutex); - return -1; - } - break; + errno = EAGAIN; + pthread_mutex_unlock(&wolfIP_mutex); + return -1; } if (entry) { wait_ret = wolfip_wait_for_event_locked(entry, POLLOUT, entry->snd_timeout_ms); @@ -1580,12 +1575,9 @@ ssize_t write(int sockfd, const void *buf, size_t len) { } if (ret == -EAGAIN) { if (nonblock) { - if (sent == 0) { - errno = EAGAIN; - pthread_mutex_unlock(&wolfIP_mutex); - return -1; - } - break; + errno = EAGAIN; + pthread_mutex_unlock(&wolfIP_mutex); + return -1; } if (entry) { wait_ret = wolfip_wait_for_event_locked(entry, POLLOUT, entry->snd_timeout_ms); @@ -1687,8 +1679,18 @@ void __attribute__((constructor)) init_wolfip_posix() { #if WOLFIP_POSIX_TCPDUMP static int tcpdump_atexit_registered; #endif - if (IPSTACK) + { + static int mutex_initialized = 0; + if (!mutex_initialized) { + pthread_mutex_init(&wolfIP_mutex, NULL); + mutex_initialized = 1; + } + } + pthread_mutex_lock(&wolfIP_mutex); + if (IPSTACK) { + pthread_mutex_unlock(&wolfIP_mutex); return; + } host_stack_ip_str = getenv("WOLFIP_HOST_IP"); if (!host_stack_ip_str || host_stack_ip_str[0] == '\0') { host_stack_ip_str = HOST_STACK_IP; @@ -1734,8 +1736,6 @@ void __attribute__((constructor)) init_wolfip_posix() { swap_socketcall(select, "select"); swap_socketcall(fcntl, "fcntl"); - pthread_mutex_init(&wolfIP_mutex, NULL); - pthread_mutex_lock(&wolfIP_mutex); wolfIP_init_static(&IPSTACK); tapdev = wolfIP_getdev(IPSTACK); if (!tapdev) { diff --git a/src/test/ipfilter_logger.c b/src/test/ipfilter_logger.c index 39b7cc6d..5cd3f4ce 100644 --- a/src/test/ipfilter_logger.c +++ b/src/test/ipfilter_logger.c @@ -288,7 +288,7 @@ static void *pt_echoclient(void *arg) } wolfSSL_set_fd(client_ssl, fd); sleep(1); - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)); + (void)setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)); printf("Connecting to echo server\n"); ret = connect(fd, (struct sockaddr *)&remote_sock, sizeof(remote_sock)); if (ret < 0) { diff --git a/src/test/test_eventloop_tun.c b/src/test/test_eventloop_tun.c index 1ca50c22..01b3cbb3 100644 --- a/src/test/test_eventloop_tun.c +++ b/src/test/test_eventloop_tun.c @@ -230,7 +230,7 @@ void *pt_echoclient(void *arg) return (void *)-1; } sleep(1); - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)); + (void)setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)); printf("Connecting to echo server\n"); old_flags = fcntl(fd, F_GETFL, 0); if (old_flags < 0) { @@ -343,7 +343,7 @@ void *pt_echoclient(void *arg) */ static void *pt_echoserver(void *arg) { - int fd, ret; + int fd, listen_fd, ret; unsigned total_r = 0; uint8_t local_buf[BUFFER_SIZE]; struct sockaddr_in local_sock = { @@ -358,21 +358,25 @@ static void *pt_echoserver(void *arg) return (void *)-1; } local_sock.sin_addr.s_addr = inet_addr(HOST_STACK_IP); - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)); + (void)setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)); ret = bind(fd, (struct sockaddr *)&local_sock, sizeof(local_sock)); if (ret < 0) { printf("test server bind: %d (%s)\n", ret, strerror(errno)); + close(fd); return (void *)-1; } ret = listen(fd, 1); if (ret < 0) { printf("test server listen: %d\n", ret); + close(fd); return (void *)-1; } + listen_fd = fd; printf("Waiting for client\n"); ret = accept(fd, NULL, NULL); if (ret < 0) { printf("test server accept: %d\n", ret); + close(listen_fd); return (void *)-1; } printf("test server: client %d connected\n", ret); @@ -381,10 +385,14 @@ static void *pt_echoserver(void *arg) ret = read(fd, local_buf + total_r, sizeof(local_buf) - total_r); if (ret < 0) { printf("failed test server read: %d (%s) \n", ret, strerror(errno)); + close(fd); + close(listen_fd); return (void *)-1; } if (ret == 0) { printf("test server read: client has closed the connection.\n"); + close(fd); + close(listen_fd); if (wolfIP_closing) return (void *)0; else diff --git a/src/test/test_ttl_expired.c b/src/test/test_ttl_expired.c index 090cd5e5..1184374b 100644 --- a/src/test/test_ttl_expired.c +++ b/src/test/test_ttl_expired.c @@ -125,7 +125,16 @@ uint32_t wolfIP_getrandom(void) return ret; } #endif - ret = (uint32_t)rand(); + { + FILE *f = fopen("/dev/urandom", "rb"); + if (f) { + size_t r = fread(&ret, sizeof(ret), 1, f); + fclose(f); + if (r == 1) + return ret; + } + } + ret = 0; return ret; } diff --git a/src/test/unit/unit_tests_api.c b/src/test/unit/unit_tests_api.c index 7f72bbd6..01776fed 100644 --- a/src/test/unit/unit_tests_api.c +++ b/src/test/unit/unit_tests_api.c @@ -3256,3 +3256,4 @@ START_TEST(test_dns_wrapper_apis) } END_TEST + diff --git a/src/wolfip.c b/src/wolfip.c index e229ea22..664f451e 100644 --- a/src/wolfip.c +++ b/src/wolfip.c @@ -2003,11 +2003,15 @@ static struct tsocket *tcp_new_socket(struct wolfIP *s) t->sock.tcp.peer_sack_count = 0; memset(t->sock.tcp.ooo, 0, sizeof(t->sock.tcp.ooo)); { +#if RXBUF_SIZE > 0xFFFF uint32_t space = RXBUF_SIZE; uint8_t shift = 0; while (shift < 14 && (space >> shift) > 0xFFFF) shift++; t->sock.tcp.rcv_wscale = shift; +#else + t->sock.tcp.rcv_wscale = 0; +#endif } /* We always include WS in the initial SYN (shift may be 0), so * mark that we offered it to accept the peer's WS in SYN-ACK. */ @@ -4505,7 +4509,7 @@ int wolfIP_sock_sendto(struct wolfIP *s, int sockfd, const void *buf, size_t len } if (sizeof(struct wolfIP_ip_packet) + payload_len > sizeof(frame)) return -WOLFIP_EINVAL; - memcpy(&icmp->type, buf, payload_len); + memcpy(frame + sizeof(struct wolfIP_ip_packet), buf, payload_len); if (icmp->type == ICMP_ECHO_REQUEST) icmp_set_echo_id(icmp, ts->src_port); icmp->csum = 0; From 2a66660d835a6b3dfe53f8a57110c98831ef8246 Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Fri, 20 Mar 2026 20:32:36 +0000 Subject: [PATCH 2/2] return short write (sent) when sent > 0 instead of -1/EAGAIN - return sent if progress was made - use PTHREAD_MUTEX_INITIALIZER instead of racy mutex_initialized guard - removed extra newline in unit_tests_api.c --- src/port/posix/bsd_socket.c | 17 ++++++++--------- src/test/unit/unit_tests_api.c | 2 -- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/port/posix/bsd_socket.c b/src/port/posix/bsd_socket.c index b0870a5f..23bc69f9 100644 --- a/src/port/posix/bsd_socket.c +++ b/src/port/posix/bsd_socket.c @@ -45,7 +45,7 @@ static __thread int in_the_stack = 1; static struct wolfIP *IPSTACK = NULL; -pthread_mutex_t wolfIP_mutex; +pthread_mutex_t wolfIP_mutex = PTHREAD_MUTEX_INITIALIZER; struct wolfip_fd_entry; int wolfIP_sock_poll(struct wolfIP *ipstack, struct pollfd *fds, nfds_t nfds, int timeout); @@ -1451,6 +1451,8 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct } if (ret == -EAGAIN) { if (nonblock) { + if (sent > 0) + break; errno = EAGAIN; pthread_mutex_unlock(&wolfIP_mutex); return -1; @@ -1470,7 +1472,7 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct if (internal_fd < 0) { pthread_mutex_unlock(&wolfIP_mutex); errno = EBADF; - return -1; + return (sent > 0) ? (ssize_t)sent : -1; } } continue; @@ -1519,6 +1521,8 @@ ssize_t send(int sockfd, const void *buf, size_t len, int flags) { } if (ret == -EAGAIN) { if (nonblock) { + if (sent > 0) + break; errno = EAGAIN; pthread_mutex_unlock(&wolfIP_mutex); return -1; @@ -1575,6 +1579,8 @@ ssize_t write(int sockfd, const void *buf, size_t len) { } if (ret == -EAGAIN) { if (nonblock) { + if (sent > 0) + break; errno = EAGAIN; pthread_mutex_unlock(&wolfIP_mutex); return -1; @@ -1679,13 +1685,6 @@ void __attribute__((constructor)) init_wolfip_posix() { #if WOLFIP_POSIX_TCPDUMP static int tcpdump_atexit_registered; #endif - { - static int mutex_initialized = 0; - if (!mutex_initialized) { - pthread_mutex_init(&wolfIP_mutex, NULL); - mutex_initialized = 1; - } - } pthread_mutex_lock(&wolfIP_mutex); if (IPSTACK) { pthread_mutex_unlock(&wolfIP_mutex); diff --git a/src/test/unit/unit_tests_api.c b/src/test/unit/unit_tests_api.c index 01776fed..9b62be7b 100644 --- a/src/test/unit/unit_tests_api.c +++ b/src/test/unit/unit_tests_api.c @@ -3255,5 +3255,3 @@ START_TEST(test_dns_wrapper_apis) ck_assert_uint_eq(s.dns_query_type, DNS_QUERY_TYPE_PTR); } END_TEST - -