From 6f210889ba1e86cc49be90291938096a8df5d131 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Tue, 3 Mar 2026 09:13:31 +0100 Subject: [PATCH 1/5] Fixed non-ETHERNET builds Also addresses Fenrir/242 --- Makefile | 7 +++++++ src/test/unit/unit_noeth.c | 10 ++++++++++ src/wolfip.c | 6 +++++- 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 src/test/unit/unit_noeth.c diff --git a/Makefile b/Makefile index 7196a5d..23a345a 100644 --- a/Makefile +++ b/Makefile @@ -352,6 +352,13 @@ endif unit-esp: build/test/unit-esp +unit-noeth: build/test/unit-noeth.o + +build/test/unit-noeth.o: src/test/unit/unit_noeth.c + @mkdir -p build/test/ + @echo "[CC] unit_noeth.c" + @$(CC) $(CFLAGS) -c src/test/unit/unit_noeth.c -o build/test/unit-noeth.o + build/test/unit-esp: src/test/unit/unit_esp.c @mkdir -p build/test/ @echo "[CC] unit_esp.c" diff --git a/src/test/unit/unit_noeth.c b/src/test/unit/unit_noeth.c new file mode 100644 index 0000000..9917a27 --- /dev/null +++ b/src/test/unit/unit_noeth.c @@ -0,0 +1,10 @@ +#include "../../../config.h" +#ifdef ETHERNET +#undef ETHERNET +#endif +#include "../../wolfip.c" + +int main(void) +{ + return 0; +} diff --git a/src/wolfip.c b/src/wolfip.c index e2cd258..160ccf2 100644 --- a/src/wolfip.c +++ b/src/wolfip.c @@ -3156,7 +3156,7 @@ static void tcp_input(struct wolfIP *S, unsigned int if_idx, t->if_idx = (uint8_t)if_idx; /* TCP segment sanity checks */ iplen = ee16(tcp->ip.len); - if (iplen > frame_len - sizeof(struct wolfIP_eth_frame)) { + if (iplen > frame_len - ETH_HEADER_LEN) { return; /* discard */ } @@ -4597,13 +4597,17 @@ static void icmp_input(struct wolfIP *s, unsigned int if_idx, struct wolfIP_ip_p ip->id = ipcounter_next(s); ip->csum = 0; iphdr_set_checksum(ip); +#ifdef ETHERNET eth_output_add_header(s, if_idx, ip->eth.src, &ip->eth, ETH_TYPE_IP); +#endif if (wolfIP_filter_notify_icmp(WOLFIP_FILT_SENDING, s, if_idx, icmp, len) != 0) return; if (wolfIP_filter_notify_ip(WOLFIP_FILT_SENDING, s, if_idx, ip, len) != 0) return; +#ifdef ETHERNET if (wolfIP_filter_notify_eth(WOLFIP_FILT_SENDING, s, if_idx, &ip->eth, len) != 0) return; +#endif if (ll && ll->send) ll->send(ll, ip, len); } From ac18050879b5a6e5e0d8b8a1d9c43019f5b3aaa7 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Tue, 3 Mar 2026 10:37:00 +0100 Subject: [PATCH 2/5] ICMP RX: don't clear readable flag Check FIFO is actually empty before clearing CB_EVENT_READABLE. Fix for F/243 --- src/test/unit/unit.c | 38 ++++++++++++++++++++++++++++++++++++++ src/wolfip.c | 3 ++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/test/unit/unit.c b/src/test/unit/unit.c index f982e5d..05a62a1 100644 --- a/src/test/unit/unit.c +++ b/src/test/unit/unit.c @@ -5353,6 +5353,43 @@ START_TEST(test_sock_recvfrom_icmp_paths) } END_TEST +START_TEST(test_sock_recvfrom_icmp_readable_stays_when_queue_nonempty) +{ + struct wolfIP s; + int icmp_sd; + struct tsocket *ts; + struct { + struct wolfIP_icmp_packet icmp; + uint8_t payload[2]; + } icmp_frame; + uint8_t rxbuf[ICMP_HEADER_LEN + 2]; + int ret; + + wolfIP_init(&s); + mock_link_init(&s); + + icmp_sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_ICMP); + ck_assert_int_gt(icmp_sd, 0); + ts = &s.icmpsockets[SOCKET_UNMARK(icmp_sd)]; + fifo_init(&ts->sock.udp.rxbuf, ts->rxmem, RXBUF_SIZE); + + memset(&icmp_frame, 0, sizeof(icmp_frame)); + icmp_frame.icmp.ip.len = ee16(IP_HEADER_LEN + ICMP_HEADER_LEN + sizeof(icmp_frame.payload)); + icmp_frame.icmp.type = ICMP_ECHO_REPLY; + icmp_frame.icmp.code = 0; + icmp_frame.payload[0] = 0xAA; + icmp_frame.payload[1] = 0xBB; + ck_assert_int_eq(fifo_push(&ts->sock.udp.rxbuf, &icmp_frame, sizeof(icmp_frame)), 0); + ck_assert_int_eq(fifo_push(&ts->sock.udp.rxbuf, &icmp_frame, sizeof(icmp_frame)), 0); + + ts->events |= CB_EVENT_READABLE; + ret = wolfIP_sock_recvfrom(&s, icmp_sd, rxbuf, sizeof(rxbuf), 0, NULL, NULL); + ck_assert_int_eq(ret, ICMP_HEADER_LEN + 2); + ck_assert_ptr_nonnull(fifo_peek(&ts->sock.udp.rxbuf)); + ck_assert_uint_ne(ts->events & CB_EVENT_READABLE, 0U); +} +END_TEST + START_TEST(test_sock_recvfrom_udp_short_addrlen) { struct wolfIP s; @@ -17348,6 +17385,7 @@ Suite *wolf_suite(void) tcase_add_test(tc_utils, test_sock_recvfrom_invalid_socket_ids); tcase_add_test(tc_utils, test_sock_recvfrom_non_socket); tcase_add_test(tc_utils, test_sock_recvfrom_icmp_success); + tcase_add_test(tc_utils, test_sock_recvfrom_icmp_readable_stays_when_queue_nonempty); tcase_add_test(tc_utils, test_sock_opts_unknown_level); tcase_add_test(tc_utils, test_sock_opts_sol_ip_unknown_optname); tcase_add_test(tc_utils, test_sock_setsockopt_recvttl); diff --git a/src/wolfip.c b/src/wolfip.c index 160ccf2..fb66835 100644 --- a/src/wolfip.c +++ b/src/wolfip.c @@ -4178,7 +4178,8 @@ int wolfIP_sock_recvfrom(struct wolfIP *s, int sockfd, void *buf, size_t len, in } memcpy(buf, &icmp->type, seg_len); fifo_pop(&ts->sock.udp.rxbuf); - ts->events &= ~CB_EVENT_READABLE; + if (fifo_peek(&ts->sock.udp.rxbuf) == NULL) + ts->events &= ~CB_EVENT_READABLE; return (int)seg_len; } else return -WOLFIP_EINVAL; From 430b236834b894416d68ae3479739be94cc396fd Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Tue, 3 Mar 2026 10:51:01 +0100 Subject: [PATCH 3/5] Fix potential overflow in debug printf Fenrir/74 --- src/test/unit/unit.c | 17 +++++++++++++++++ src/wolfip_debug.c | 5 ++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/test/unit/unit.c b/src/test/unit/unit.c index 05a62a1..5fa9eb3 100644 --- a/src/test/unit/unit.c +++ b/src/test/unit/unit.c @@ -20,6 +20,8 @@ */ #include "check.h" #include "../../../config.h" +#undef DEBUG_UDP +#define DEBUG_UDP 1 #undef CONFIG_IPFILTER #define CONFIG_IPFILTER 1 #undef WOLFIP_MAX_INTERFACES @@ -5353,6 +5355,18 @@ START_TEST(test_sock_recvfrom_icmp_paths) } END_TEST +#ifdef DEBUG_UDP +START_TEST(test_wolfip_print_udp_short_len_no_oob) +{ + struct wolfIP_udp_datagram udp; + + memset(&udp, 0, sizeof(udp)); + udp.len = ee16(4); /* Invalid: shorter than UDP header. */ + wolfIP_print_udp(&udp); +} +END_TEST +#endif + START_TEST(test_sock_recvfrom_icmp_readable_stays_when_queue_nonempty) { struct wolfIP s; @@ -17385,6 +17399,9 @@ Suite *wolf_suite(void) tcase_add_test(tc_utils, test_sock_recvfrom_invalid_socket_ids); tcase_add_test(tc_utils, test_sock_recvfrom_non_socket); tcase_add_test(tc_utils, test_sock_recvfrom_icmp_success); +#ifdef DEBUG_UDP + tcase_add_test(tc_utils, test_wolfip_print_udp_short_len_no_oob); +#endif tcase_add_test(tc_utils, test_sock_recvfrom_icmp_readable_stays_when_queue_nonempty); tcase_add_test(tc_utils, test_sock_opts_unknown_level); tcase_add_test(tc_utils, test_sock_opts_sol_ip_unknown_optname); diff --git a/src/wolfip_debug.c b/src/wolfip_debug.c index 7217ff1..5ce9f70 100644 --- a/src/wolfip_debug.c +++ b/src/wolfip_debug.c @@ -89,8 +89,11 @@ static void wolfIP_print_udp(struct wolfIP_udp_datagram * udp) { /* show first 16 printable chars of payload */ uint16_t max_len = 16; - size_t print_len = (len - 8) < max_len ? (len - 8): max_len; size_t i = 0; + size_t print_len = 0; + if (len <= UDP_HEADER_LEN) + return; + print_len = (len - 8) < max_len ? (len - 8): max_len; memset(payload_str, '\0', sizeof(payload_str)); memcpy(payload_str, udp->data, print_len); for (i = 0; i < print_len; i++) { From d9c705819b1a097fb5b5aa06bbdaa1096e91811a Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Tue, 3 Mar 2026 10:54:27 +0100 Subject: [PATCH 4/5] Reinforce arguments check in wolfIP_sock_getpeer() Fixes F/138 --- src/test/unit/unit.c | 1 + src/wolfip.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/unit/unit.c b/src/test/unit/unit.c index 5fa9eb3..9bfb1db 100644 --- a/src/test/unit/unit.c +++ b/src/test/unit/unit.c @@ -4644,6 +4644,7 @@ START_TEST(test_sock_getpeername_errors) ck_assert_int_gt(tcp_sd, 0); ck_assert_int_eq(wolfIP_sock_getpeername(&s, tcp_sd, NULL, &len), -1); ck_assert_int_eq(wolfIP_sock_getpeername(&s, tcp_sd, (struct wolfIP_sockaddr *)&sin, &len), -1); + ck_assert_int_eq(wolfIP_sock_getpeername(&s, tcp_sd, (struct wolfIP_sockaddr *)&sin, NULL), -1); } END_TEST diff --git a/src/wolfip.c b/src/wolfip.c index fb66835..d948b1c 100644 --- a/src/wolfip.c +++ b/src/wolfip.c @@ -4554,7 +4554,7 @@ int wolfIP_sock_getpeername(struct wolfIP *s, int sockfd, struct wolfIP_sockaddr return -WOLFIP_EINVAL; ts = &s->tcpsockets[SOCKET_UNMARK(sockfd)]; - if (!sin || *addrlen < sizeof(struct wolfIP_sockaddr_in)) + if (!sin || !addrlen || *addrlen < sizeof(struct wolfIP_sockaddr_in)) return -1; sin->sin_family = AF_INET; sin->sin_port = ee16(ts->dst_port); From 51baae0e8869951b7260aa5ab8597f82ab703341 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Tue, 3 Mar 2026 11:02:07 +0100 Subject: [PATCH 5/5] dns_send_query: fix tokens composition, max len F/140 --- src/test/unit/unit.c | 37 +++++++++++++++++++++++++++++++++++++ src/wolfip.c | 16 +++++++++++----- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/test/unit/unit.c b/src/test/unit/unit.c index 9bfb1db..48a9b86 100644 --- a/src/test/unit/unit.c +++ b/src/test/unit/unit.c @@ -5818,6 +5818,42 @@ START_TEST(test_dns_send_query_errors) ck_assert_int_eq(dns_send_query(&s, "example.com", &id, DNS_A), -16); } END_TEST +START_TEST(test_dns_send_query_invalid_name) +{ + struct wolfIP s; + uint16_t id = 0; + char name[260]; + size_t pos = 0; + + wolfIP_init(&s); + mock_link_init(&s); + s.dns_server = 0x08080808U; + s.dns_id = 0; + + memset(name, 'a', 64); + name[64] = '.'; + memcpy(name + 65, "com", 3); + name[68] = 0; + ck_assert_int_eq(dns_send_query(&s, name, &id, DNS_A), -22); + + s.dns_id = 0; + memset(name, 'a', sizeof(name)); + pos = 0; + memset(name + pos, 'a', 63); + pos += 63; + name[pos++] = '.'; + memset(name + pos, 'b', 63); + pos += 63; + name[pos++] = '.'; + memset(name + pos, 'c', 63); + pos += 63; + name[pos++] = '.'; + memset(name + pos, 'd', 63); + pos += 63; + name[pos] = 0; + ck_assert_int_eq(dns_send_query(&s, name, &id, DNS_A), -22); +} +END_TEST START_TEST(test_fifo_push_and_pop) { struct fifo f; struct pkt_desc *desc, *desc2; @@ -17528,6 +17564,7 @@ Suite *wolf_suite(void) tcase_add_test(tc_utils, test_dns_skip_and_copy_name); tcase_add_test(tc_utils, test_sock_opts_and_names); tcase_add_test(tc_utils, test_dns_send_query_errors); + tcase_add_test(tc_utils, test_dns_send_query_invalid_name); tcase_add_test(tc_utils, test_dns_wrapper_apis); tcase_add_test(tc_utils, test_wolfip_static_instance_apis); tcase_add_test(tc_utils, test_tcp_rto_cb_resets_flags_and_arms_timer); diff --git a/src/wolfip.c b/src/wolfip.c index d948b1c..2fbe3f7 100644 --- a/src/wolfip.c +++ b/src/wolfip.c @@ -5477,6 +5477,8 @@ void wolfIP_recv_ex(struct wolfIP *s, unsigned int if_idx, void *buf, uint32_t l #define DNS_QUERY_TYPE_NONE 0 #define DNS_QUERY_TYPE_A 1 #define DNS_QUERY_TYPE_PTR 2 +#define MAX_DNS_NAME_LEN 255 +#define MAX_DNS_LABEL_LEN 63 struct PACKED dns_header { uint16_t id; @@ -5696,8 +5698,9 @@ static int dns_send_query(struct wolfIP *s, const char *dname, uint16_t *id, char *q_name, *tok_start, *tok_end; struct wolfIP_sockaddr_in dns_srv; uint32_t tok_len = 0; + uint32_t label_len = 0; if (!dname || !id) return -22; - if (strlen(dname) > 256) return -22; /* Invalid arguments */ + if (strlen(dname) > MAX_DNS_NAME_LEN) return -22; /* Invalid arguments */ if (s->dns_server == 0) return -101; /* Network unreachable: No DNS server configured */ if (s->dns_id != 0) return -16; /* DNS query already in progress */ if (s->dns_udp_sd <= 0) { @@ -5723,11 +5726,14 @@ static int dns_send_query(struct wolfIP *s, const char *dname, uint16_t *id, while ((*tok_end != '.') && (*tok_end != 0)) { tok_end++; } - *q_name = tok_end - tok_start; + label_len = (uint32_t)(tok_end - tok_start); + if (label_len > MAX_DNS_LABEL_LEN) return -22; + if (tok_len + label_len + 1 > MAX_DNS_NAME_LEN) return -22; + *q_name = (char)label_len; q_name++; - memcpy(q_name, tok_start, tok_end - tok_start); - q_name += tok_end - tok_start; - tok_len += (tok_end - tok_start) + 1; + memcpy(q_name, tok_start, label_len); + q_name += label_len; + tok_len += label_len + 1; if (*tok_end == 0) break; tok_start = tok_end + 1;