diff --git a/src/port/posix/bsd_socket.c b/src/port/posix/bsd_socket.c index c2798549..7ecd5ac6 100644 --- a/src/port/posix/bsd_socket.c +++ b/src/port/posix/bsd_socket.c @@ -298,10 +298,20 @@ static int wolfip_fd_alloc(int internal_fd, int nonblock) host_fcntl(pipefds[0], F_SETFL, O_NONBLOCK); host_fcntl(pipefds[1], F_SETFL, O_NONBLOCK); } else { - fcntl(pipefds[0], F_SETFD, FD_CLOEXEC); - fcntl(pipefds[1], F_SETFD, FD_CLOEXEC); - fcntl(pipefds[0], F_SETFL, O_NONBLOCK); - fcntl(pipefds[1], F_SETFL, O_NONBLOCK); + /* Resolve the real libc fcntl via dlsym to avoid recursing into our + * interposed fcntl(), which would deadlock on wolfIP_mutex. */ + int (*real_fcntl)(int, int, ...) = (int (*)(int, int, ...))dlsym(RTLD_NEXT, "fcntl"); + if (!real_fcntl || + real_fcntl(pipefds[0], F_SETFD, FD_CLOEXEC) < 0 || + real_fcntl(pipefds[1], F_SETFD, FD_CLOEXEC) < 0 || + real_fcntl(pipefds[0], F_SETFL, O_NONBLOCK) < 0 || + real_fcntl(pipefds[1], F_SETFL, O_NONBLOCK) < 0) { + if (host_close) { + host_close(pipefds[0]); + host_close(pipefds[1]); + } + return -errno; + } } if (pipefds[0] < 0 || pipefds[0] >= WOLFIP_MAX_PUBLIC_FDS || wolfip_fd_entries[pipefds[0]].in_use) { if (host_close) { @@ -524,8 +534,6 @@ static int wolfip_calc_msghdr_len(const struct msghdr *msg, size_t *total_len) return -WOLFIP_EINVAL; for (i = 0; i < msg->msg_iovlen; i++) { const struct iovec *iov = &msg->msg_iov[i]; - if (!iov) - return -WOLFIP_EINVAL; if (!iov->iov_base && iov->iov_len != 0) return -WOLFIP_EINVAL; if (SIZE_MAX - len < iov->iov_len) @@ -906,7 +914,7 @@ int wolfIP_sock_recvmsg(struct wolfIP *ipstack, int sockfd, struct msghdr *msg, buf = (uint8_t *)msg->msg_iov[0].iov_base; } else if (total_len > 0) { if (total_len > sizeof(stack_buf)) { - heap_buf = (uint8_t *)malloc(total_len); + heap_buf = (uint8_t *)calloc(total_len, 1); if (!heap_buf) return -WOLFIP_ENOMEM; buf = heap_buf; @@ -936,8 +944,6 @@ int wolfIP_sock_recvmsg(struct wolfIP *ipstack, int sockfd, struct msghdr *msg, msg->msg_flags = 0; wolfip_fill_ttl_control(ipstack, sockfd, msg); } - if (ret == -WOLFIP_EAGAIN) - return -EWOULDBLOCK; return ret; } @@ -1160,17 +1166,21 @@ int socket(int domain, int type, int protocol) { if (in_the_stack) { return host_socket(domain, type, protocol); } + pthread_mutex_lock(&wolfIP_mutex); internal_fd = wolfIP_sock_socket(IPSTACK, domain, base_type, protocol); if (internal_fd < 0) { + pthread_mutex_unlock(&wolfIP_mutex); errno = -internal_fd; return -1; } public_fd = wolfip_fd_alloc(internal_fd, (type & SOCK_NONBLOCK) ? 1 : 0); if (public_fd < 0) { wolfIP_sock_close(IPSTACK, internal_fd); + pthread_mutex_unlock(&wolfIP_mutex); errno = -public_fd; return -1; } + pthread_mutex_unlock(&wolfIP_mutex); return public_fd; } @@ -1257,6 +1267,12 @@ static int wolfip_accept_common(int sockfd, struct sockaddr *addr, socklen_t *ad pthread_mutex_unlock(&wolfIP_mutex); host_poll(&pfd, 1, -1); pthread_mutex_lock(&wolfIP_mutex); + entry = wolfip_entry_from_public(sockfd); + if (!entry) { + errno = EBADF; + pthread_mutex_unlock(&wolfIP_mutex); + return -1; + } wolfip_drain_pipe_locked(entry); } } while (internal_ret == -EAGAIN); @@ -1434,12 +1450,12 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct } if (ret == -EAGAIN) { if (nonblock) { - if (sent == 0) + if (sent == 0) { errno = EAGAIN; - else - errno = 0; - pthread_mutex_unlock(&wolfIP_mutex); - return (sent == 0) ? -1 : (ssize_t)sent; + pthread_mutex_unlock(&wolfIP_mutex); + return -1; + } + break; } if (entry) { wait_ret = wolfip_wait_for_event_locked(entry, POLLOUT, entry->snd_timeout_ms); @@ -1452,6 +1468,12 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct pthread_mutex_unlock(&wolfIP_mutex); usleep(1000); pthread_mutex_lock(&wolfIP_mutex); + internal_fd = wolfip_fd_internal_from_public(sockfd); + if (internal_fd < 0) { + pthread_mutex_unlock(&wolfIP_mutex); + errno = EBADF; + return (sent == 0) ? -1 : (ssize_t)sent; + } } continue; } @@ -1504,9 +1526,7 @@ ssize_t send(int sockfd, const void *buf, size_t len, int flags) { pthread_mutex_unlock(&wolfIP_mutex); return -1; } - pthread_mutex_unlock(&wolfIP_mutex); - errno = 0; - return (ssize_t)sent; + break; } if (entry) { wait_ret = wolfip_wait_for_event_locked(entry, POLLOUT, entry->snd_timeout_ms); @@ -1565,9 +1585,7 @@ ssize_t write(int sockfd, const void *buf, size_t len) { pthread_mutex_unlock(&wolfIP_mutex); return -1; } - pthread_mutex_unlock(&wolfIP_mutex); - errno = 0; - return (ssize_t)sent; + break; } if (entry) { wait_ret = wolfip_wait_for_event_locked(entry, POLLOUT, entry->snd_timeout_ms); @@ -1631,6 +1649,34 @@ void *wolfIP_sock_posix_ip_loop(void *arg) { return NULL; } +static int wolfip_validate_ipv4(const char *s) +{ + int parts = 0, digits = 0; + unsigned int val = 0; + if (!s || !*s) + return 0; + while (*s) { + if (*s >= '0' && *s <= '9') { + digits++; + if (digits > 3) + return 0; + val = val * 10 + (unsigned int)(*s - '0'); + if (val > 255) + return 0; + } else if (*s == '.') { + if (digits == 0) + return 0; + parts++; + digits = 0; + val = 0; + } else { + return 0; + } + s++; + } + return (parts == 3 && digits > 0); +} + void __attribute__((constructor)) init_wolfip_posix() { struct in_addr host_stack_ip; const char *host_stack_ip_str; @@ -1657,7 +1703,12 @@ void __attribute__((constructor)) init_wolfip_posix() { } fprintf(stderr, "wolfIP: Serving process PID=%d, TID=%x\n", getpid(), (unsigned short)pthread_self()); - inet_aton(host_stack_ip_str, &host_stack_ip); + if (!wolfip_validate_ipv4(host_stack_ip_str) || + inet_aton(host_stack_ip_str, &host_stack_ip) == 0) { + fprintf(stderr, "Invalid WOLFIP_HOST_IP, using default\n"); + host_stack_ip_str = HOST_STACK_IP; + inet_aton(host_stack_ip_str, &host_stack_ip); + } swap_socketcall(socket, "socket"); swap_socketcall(bind, "bind"); swap_socketcall(listen, "listen"); @@ -1684,8 +1735,14 @@ void __attribute__((constructor)) init_wolfip_posix() { 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) { + fprintf(stderr, "wolfIP_getdev returned NULL\n"); + pthread_mutex_unlock(&wolfIP_mutex); + return; + } #if WOLFIP_USE_VDE { const char *vde_socket = getenv("VDE_SOCKET_PATH"); @@ -1694,12 +1751,14 @@ void __attribute__((constructor)) init_wolfip_posix() { } if (vde_init(tapdev, vde_socket, NULL, NULL) < 0) { perror("vde init"); + pthread_mutex_unlock(&wolfIP_mutex); return; } } #else if (tap_init(tapdev, "wtcp0", host_stack_ip.s_addr) < 0) { perror("tap init"); + pthread_mutex_unlock(&wolfIP_mutex); return; } #endif @@ -1710,8 +1769,16 @@ void __attribute__((constructor)) init_wolfip_posix() { } wolfIP_start_tcpdump((tapdev && tapdev->ifname[0]) ? tapdev->ifname : "wtcp0"); #endif + if (!wolfip_validate_ipv4(wolfip_ip_str) || !wolfip_validate_ipv4(wolfip_mask_str) || + !wolfip_validate_ipv4(host_stack_ip_str)) { + fprintf(stderr, "Invalid IP configuration, falling back to defaults\n"); + wolfip_ip_str = WOLFIP_IP; + wolfip_mask_str = "255.255.255.0"; + host_stack_ip_str = HOST_STACK_IP; + } wolfIP_ipconfig_set(IPSTACK, atoip4(wolfip_ip_str), atoip4(wolfip_mask_str), atoip4(host_stack_ip_str)); + pthread_mutex_unlock(&wolfIP_mutex); fprintf(stderr, "IP: manually configured - %s\n", wolfip_ip_str); /* Avoid penalizing startup fairness across stacks: once init is done, * hand control to the poll thread immediately. */ diff --git a/src/port/posix/tap_linux.c b/src/port/posix/tap_linux.c index 745da042..ea7440ad 100644 --- a/src/port/posix/tap_linux.c +++ b/src/port/posix/tap_linux.c @@ -137,6 +137,7 @@ int tap_init(struct wolfIP_ll_dev *ll, const char *ifname, uint32_t host_ip) memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ-1] = '\0'; if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) < 0) { perror("ioctl SIOCGIFFLAGS"); close(sock_fd); @@ -173,6 +174,7 @@ int tap_init(struct wolfIP_ll_dev *ll, const char *ifname, uint32_t host_ip) close(sock_fd); return -1; } + close(sock_fd); printf("Successfully initialized tap device %s\n", ifname); return 0; } diff --git a/src/test/esp/esp_server.c b/src/test/esp/esp_server.c index 59e99f3f..9c4665bc 100644 --- a/src/test/esp/esp_server.c +++ b/src/test/esp/esp_server.c @@ -145,7 +145,7 @@ int main(int argc, char * argv[]) } // Create a socket - if ((server_fd = socket(AF_INET, type, 0)) == 0) { + if ((server_fd = socket(AF_INET, type, 0)) < 0) { perror("Socket failed"); exit(EXIT_FAILURE); } diff --git a/src/test/esp/test_esp.c b/src/test/esp/test_esp.c index 3f767fce..b92ccdc0 100644 --- a/src/test/esp/test_esp.c +++ b/src/test/esp/test_esp.c @@ -245,7 +245,7 @@ static 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) { @@ -361,7 +361,7 @@ static 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 = { @@ -376,21 +376,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); @@ -399,10 +403,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/tcp_echo.c b/src/test/tcp_echo.c index bf528513..053e3002 100644 --- a/src/test/tcp_echo.c +++ b/src/test/tcp_echo.c @@ -36,7 +36,7 @@ int main() { char buffer[BUFFER_SIZE]; // Create a socket - if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { + if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Socket failed"); exit(EXIT_FAILURE); } @@ -80,7 +80,5 @@ int main() { printf("Client disconnected\n"); close(client_fd); } - - close(server_fd); - return 0; + /* NOTREACHED */ } diff --git a/src/test/tcp_netcat_poll.c b/src/test/tcp_netcat_poll.c index 962ff853..062d3d28 100644 --- a/src/test/tcp_netcat_poll.c +++ b/src/test/tcp_netcat_poll.c @@ -81,7 +81,16 @@ int main() { if (bytes_read > 0) { // Write stdin data to the socket if (new_socket != -1) { - send(new_socket, buffer, bytes_read, 0); + ssize_t off = 0; + while (off < bytes_read) { + ssize_t n = send(new_socket, buffer + off, + bytes_read - off, 0); + if (n < 0) { + perror("send"); + break; + } + off += n; + } } } } @@ -115,7 +124,5 @@ int main() { } } } - - close(server_fd); - return 0; + /* NOTREACHED */ } diff --git a/src/test/tcp_netcat_select.c b/src/test/tcp_netcat_select.c index 7921a844..3b10a556 100644 --- a/src/test/tcp_netcat_select.c +++ b/src/test/tcp_netcat_select.c @@ -82,7 +82,16 @@ int main() { ssize_t bytes_read = read(STDIN_FILENO, buffer, sizeof(buffer)); if (bytes_read > 0 && new_socket != -1) { // Write stdin data to the socket - send(new_socket, buffer, bytes_read, 0); + ssize_t off = 0; + while (off < bytes_read) { + ssize_t n = send(new_socket, buffer + off, + bytes_read - off, 0); + if (n < 0) { + perror("send"); + break; + } + off += n; + } } } @@ -113,7 +122,5 @@ int main() { } } } - - close(server_fd); - return 0; + /* NOTREACHED */ } diff --git a/src/test/test_dhcp_dns.c b/src/test/test_dhcp_dns.c index 3b35715e..9e368b9d 100644 --- a/src/test/test_dhcp_dns.c +++ b/src/test/test_dhcp_dns.c @@ -140,7 +140,7 @@ static int test_loop(struct wolfIP *s, int active_close) */ 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 = { @@ -155,21 +155,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); @@ -178,10 +182,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_eventloop.c b/src/test/test_eventloop.c index 4ffbf8c9..4c4fcc18 100644 --- a/src/test/test_eventloop.c +++ b/src/test/test_eventloop.c @@ -228,7 +228,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) { @@ -339,7 +339,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 = { @@ -354,21 +354,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); @@ -377,10 +381,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_native_wolfssl.c b/src/test/test_native_wolfssl.c index f06b5194..406a0c3e 100644 --- a/src/test/test_native_wolfssl.c +++ b/src/test/test_native_wolfssl.c @@ -210,7 +210,7 @@ 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"); /* Use non-blocking connect with select() loop for robustness */ diff --git a/src/test/test_ttl_expired.c b/src/test/test_ttl_expired.c index a10c4bcc..090cd5e5 100644 --- a/src/test/test_ttl_expired.c +++ b/src/test/test_ttl_expired.c @@ -32,6 +32,9 @@ #include #include #include +#ifdef __linux__ +#include +#endif #include #include "config.h" @@ -106,12 +109,24 @@ static uint16_t ones_csum(const void *buf, size_t len) acc += *((const uint8_t *)p); while (acc >> 16) acc = (acc & 0xFFFF) + (acc >> 16); - return (uint16_t)~acc; + return (uint16_t)(~acc & 0xFFFF); } uint32_t wolfIP_getrandom(void) { - return (uint32_t)rand(); + uint32_t ret; +#ifdef __linux__ + { + ssize_t n; + do { + n = getrandom(&ret, sizeof(ret), 0); + } while (n < 0 && errno == EINTR); + if (n == (ssize_t)sizeof(ret)) + return ret; + } +#endif + ret = (uint32_t)rand(); + return ret; } struct mem_link { diff --git a/src/test/test_wolfssl_forwarding.c b/src/test/test_wolfssl_forwarding.c index 0574ab6b..1ac3b4dd 100644 --- a/src/test/test_wolfssl_forwarding.c +++ b/src/test/test_wolfssl_forwarding.c @@ -601,8 +601,16 @@ int main(void) mem_link_attach(wolfIP_getdev_ex(router_stack, 1), &link_router_server, 0, "rt1", mac_router1); - mem_link_attach(wolfIP_getdev(server_stack), &link_router_server, 1, - "srv0", mac_server); + { + struct wolfIP_ll_dev *srv_dev = wolfIP_getdev(server_stack); + if (!srv_dev) { + fprintf(stderr, "wolfIP_getdev(server_stack) returned NULL\n"); + ret = 1; + goto cleanup; + } + mem_link_attach(srv_dev, &link_router_server, 1, + "srv0", mac_server); + } wolfIP_ipconfig_set_ex(router_stack, 0, router_lan_ip4, IP4(255,255,255,0), IP4(0,0,0,0)); wolfIP_ipconfig_set_ex(router_stack, 1, router_wan_ip4, IP4(255,255,255,0), IP4(0,0,0,0)); diff --git a/src/wolfip.c b/src/wolfip.c index 25f4178f..7900b861 100644 --- a/src/wolfip.c +++ b/src/wolfip.c @@ -188,7 +188,7 @@ static inline void fifo_align_tail(struct fifo *f) f->tail = 0; f->h_wrap = 0; } - if (f->tail >= f->size) + if (f->size > 0 && f->tail >= f->size) f->tail %= f->size; if ((f->tail + sizeof(struct pkt_desc)) > f->size) f->tail = 0; @@ -2552,7 +2552,7 @@ static uint16_t icmp_checksum(struct wolfIP_icmp_packet *icmp, uint16_t len) while (sum >> 16) { sum = (sum & 0xffff) + (sum >> 16); } - return (uint16_t)~sum; + return (uint16_t)(~sum & 0xFFFF); } static void iphdr_set_checksum(struct wolfIP_ip_packet *ip) @@ -2742,6 +2742,8 @@ static int tcp_process_ts(struct tsocket *t, const struct wolfIP_tcp_seg *tcp, tcp_parse_options(tcp, frame_len, &po); if (!po.ts_found) return -1; + if (!t->S) + return -1; /* Socket was closed; ignore. */ t->sock.tcp.last_ts = ee32(po.ts_val); if (po.ts_ecr == 0) return -1; /* No echoed timestamp; fall back to coarse RTT. */ @@ -3167,6 +3169,8 @@ static void tcp_input(struct wolfIP *S, unsigned int if_idx, uint32_t tcplen; uint32_t iplen; struct tsocket *t = &S->tcpsockets[i]; + if (t->proto == 0 || t->S == NULL) + continue; if (t->src_port == ee16(tcp->dst_port)) { t->if_idx = (uint8_t)if_idx; /* TCP segment sanity checks */ @@ -4086,6 +4090,8 @@ int wolfIP_sock_sendto(struct wolfIP *s, int sockfd, const void *buf, size_t len ts->local_ip = primary->ip; } } + if (sizeof(struct wolfIP_ip_packet) + payload_len > sizeof(frame)) + return -WOLFIP_EINVAL; memcpy(&icmp->type, buf, payload_len); if (icmp->type == ICMP_ECHO_REQUEST) icmp_set_echo_id(icmp, ts->src_port); @@ -4168,6 +4174,8 @@ int wolfIP_sock_recvfrom(struct wolfIP *s, int sockfd, void *buf, size_t len, in if (fifo_len(&ts->sock.udp.rxbuf) == 0) return -WOLFIP_EAGAIN; desc = fifo_peek(&ts->sock.udp.rxbuf); + if (!desc) + return -WOLFIP_EAGAIN; udp = (struct wolfIP_udp_datagram *)(ts->rxmem + desc->pos + sizeof(*desc)); if (ee16(udp->len) < UDP_HEADER_LEN) { fifo_pop(&ts->sock.udp.rxbuf); @@ -4903,8 +4911,6 @@ static int dhcp_parse_ack(struct wolfIP *s, struct dhcp_msg *msg, uint32_t msg_l } opt += 2 + len; } - if (!saw_end) - return -1; return -1; } @@ -5812,7 +5818,12 @@ void dns_callback(int dns_sd, uint16_t ev, void *arg) return; } if (s->dns_query_type == DNS_QUERY_TYPE_A && ee16(rr->type) == DNS_A && rdlen >= 4) { - uint32_t ip = (buf[pos + 3] & 0xFF) | + uint32_t ip; + if (pos + 4 > dns_len) { + s->dns_id = 0; + return; + } + ip = (buf[pos + 3] & 0xFF) | ((buf[pos + 2] & 0xFF) << 8) | ((buf[pos + 1] & 0xFF) << 16) | ((buf[pos + 0] & 0xFF) << 24);