Skip to content

Commit d70271b

Browse files
authored
Merge pull request #164 from danielinux/fenrir-fixes-2026-08-24
Fenrir fixes 2026 08 24
2 parents 2943bbc + 8f41e29 commit d70271b

9 files changed

Lines changed: 1163 additions & 280 deletions

File tree

src/test/unit/unit.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ Suite *wolf_suite(void)
176176
tcase_add_test(tc_utils, test_wolfip_dns_server_get_returns_value_and_validates_args);
177177
tcase_add_test(tc_utils, test_wolfip_poll_executes_timers_and_callbacks);
178178
tcase_add_test(tc_utils, test_wolfip_poll_drains_all_expired_timers_in_one_pass);
179+
tcase_add_test(tc_utils, test_wolfip_poll_tick_wrap_timer_due_after_wrap);
180+
tcase_add_test(tc_utils, test_wolfip_poll_tick_wrap_timer_already_due_fires_now);
181+
tcase_add_test(tc_utils, test_wolfip_poll_tick_wrap_mixed_timer_ordering);
179182
tcase_add_test(tc_utils, test_wolfip_poll_preserves_tcp_events_raised_during_callback);
180183
tcase_add_test(tc_utils, test_wolfip_poll_limits_device_drain_to_poll_budget);
181184
tcase_add_test(tc_utils, test_filter_notify_tcp_metadata);
@@ -254,6 +257,7 @@ Suite *wolf_suite(void)
254257
tcase_add_test(tc_utils, test_sock_accept_negative_fd);
255258
tcase_add_test(tc_utils, test_sock_accept_invalid_tcp_fd);
256259
tcase_add_test(tc_utils, test_sock_accept_success_sets_addr);
260+
tcase_add_test(tc_utils, test_sock_accept_listener_resets_paws_state);
257261
tcase_add_test(tc_utils, test_sock_accept_no_available_socket);
258262
tcase_add_test(tc_utils, test_sock_accept_no_free_socket_syn_rcvd);
259263
tcase_add_test(tc_utils, test_sock_accept_listen_no_connection);
@@ -543,7 +547,10 @@ Suite *wolf_suite(void)
543547
tcase_add_test(tc_utils, test_dns_callback_rejects_a_record_with_wrong_rdlength);
544548
tcase_add_test(tc_utils, test_dhcp_parse_offer_option_overload);
545549
tcase_add_test(tc_utils,
546-
test_dhcp_parse_offer_option_split_across_region_boundary);
550+
test_dhcp_parse_offer_option_split_across_region_boundary_rejected);
551+
tcase_add_test(tc_utils, test_dhcp_parse_offer_main_field_without_end_rejected);
552+
tcase_add_test(tc_utils,
553+
test_dhcp_parse_offer_compliant_overloaded_offer_accepted);
547554
tcase_add_test(tc_utils, test_dhcp_discover_first_retry_delay_rfc2131);
548555
tcase_add_test(tc_utils, test_dhcp_discover_sets_broadcast_flag);
549556
tcase_add_test(tc_utils, test_dhcp_request_broadcast_flag_by_state);
@@ -956,6 +963,7 @@ Suite *wolf_suite(void)
956963
tcase_add_test(tc_proto, test_icmp_input_dest_unreach_port_unreachable_mismatched_orig_src_port_ignored);
957964
tcase_add_test(tc_proto, test_icmp_input_dest_unreach_port_unreachable_mismatched_orig_dst_port_ignored);
958965
tcase_add_test(tc_proto, test_udp_sendto_and_recvfrom);
966+
tcase_add_test(tc_proto, test_udp_wildcard_bind_receives_all_local_addrs);
959967
tcase_add_test(tc_proto, test_udp_sendto_respects_mtu_api);
960968
tcase_add_test(tc_proto, test_udp_recvfrom_sets_remote_ip);
961969
tcase_add_test(tc_proto, test_udp_recvfrom_null_src_addr_len);
@@ -1438,11 +1446,13 @@ Suite *wolf_suite(void)
14381446
tcase_add_test(tc_core, test_dhcp_msg_type_nak_absent_server_id_rejected);
14391447
tcase_add_test(tc_core, test_dhcp_msg_type_nak_matching_server_id_accepted);
14401448
tcase_add_test(tc_core, test_dhcp_parse_offer_type_ack_not_offer_rejected);
1449+
tcase_add_test(tc_core, test_dhcp_parse_offer_options_before_msg_type_accepted);
1450+
tcase_add_test(tc_core, test_dhcp_parse_offer_bad_server_id_before_msg_type_rejected);
14411451
tcase_add_test(tc_core, test_dhcp_parse_offer_subnet_mask_len_lt4_rejected);
14421452
tcase_add_test(tc_core, test_dhcp_parse_offer_inner_truncated_opt2_rejected);
14431453
tcase_add_test(tc_core, test_dhcp_parse_offer_inner_truncated_data_rejected);
14441454
tcase_add_test(tc_core, test_dhcp_parse_offer_inner_pad_then_end);
1445-
tcase_add_test(tc_core, test_dhcp_parse_offer_outer_end_with_state_already_set);
1455+
tcase_add_test(tc_core, test_dhcp_parse_offer_non_offer_with_stale_state_rejected);
14461456
tcase_add_test(tc_core, test_dhcp_parse_ack_mismatched_server_id_rejected);
14471457
tcase_add_test(tc_core, test_dhcp_parse_ack_server_id_len_lt4_rejected);
14481458
tcase_add_test(tc_core, test_dhcp_parse_ack_offer_ip_len_lt4_rejected);
@@ -1454,6 +1464,8 @@ Suite *wolf_suite(void)
14541464
tcase_add_test(tc_core, test_dhcp_parse_ack_rebind_time_len_lt4_rejected);
14551465
tcase_add_test(tc_core, test_dhcp_parse_ack_no_ip_after_ack_rejected);
14561466
tcase_add_test(tc_core, test_dhcp_parse_ack_no_mask_after_ack_rejected);
1467+
tcase_add_test(tc_core, test_dhcp_parse_ack_options_before_msg_type_accepted);
1468+
tcase_add_test(tc_core, test_dhcp_parse_ack_mismatched_server_id_before_msg_type_rejected);
14571469
tcase_add_test(tc_core, test_dhcp_parse_ack_with_renewal_and_rebind_times);
14581470
tcase_add_test(tc_core, test_dhcp_parse_ack_dns_already_set_skipped);
14591471
tcase_add_test(tc_core, test_dhcp_parse_ack_inner_pad_bytes_skipped);
@@ -1476,7 +1488,7 @@ Suite *wolf_suite(void)
14761488
tcase_add_test(tc_core, test_dhcp_nak_relearns_dns_server);
14771489
tcase_add_test(tc_core, test_dhcp_lease_expiry_keeps_pinned_dns_server);
14781490
tcase_add_test(tc_core, test_dhcp_public_apis_null_stack_safe);
1479-
/* --- unit_tests_ip_arp_recv.c (35 tests) --- */
1491+
/* --- unit_tests_ip_arp_recv.c (38 tests) --- */
14801492
tcase_add_test(tc_core, test_ip_recv_limited_broadcast_dst_is_local);
14811493
tcase_add_test(tc_core, test_ip_recv_directed_broadcast_dst_is_local);
14821494
tcase_add_test(tc_core, test_ip_recv_ipaddr_any_dst_is_local);
@@ -1489,6 +1501,9 @@ Suite *wolf_suite(void)
14891501
tcase_add_test(tc_core, test_ip_recv_forward_link_local_src_rpf_drop);
14901502
tcase_add_test(tc_core, test_ip_recv_forward_self_ip_src_dropped);
14911503
tcase_add_test(tc_core, test_ip_recv_l2_broadcast_frame_not_forwarded);
1504+
tcase_add_test(tc_core, test_ip_recv_forward_no_route_dropped_not_dispatched);
1505+
tcase_add_test(tc_core, test_ip_recv_l2_group_not_locally_deliverable_dropped);
1506+
tcase_add_test(tc_core, test_ip_recv_l2_group_dhcp_still_reaches_local_udp);
14921507
tcase_add_test(tc_core, test_ip_recv_options_nop_delivered);
14931508
tcase_add_test(tc_core, test_ip_recv_options_rr_stripped_and_delivered);
14941509
tcase_add_test(tc_core, test_ip_recv_options_bad_length_aborts_parse);

src/test/unit/unit_esp.c

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2236,7 +2236,7 @@ static int state_write_calls = 0;
22362236
static uint32_t state_last_oseq = 0;
22372237

22382238
static int state_test_read_cb(const uint8_t *spi, uint32_t *oseq,
2239-
uint32_t *hi_seq, uint32_t *bitmap)
2239+
uint32_t *hi_seq, uint64_t *bitmap)
22402240
{
22412241
state_read_calls++;
22422242
if (memcmp(spi, state_test_spi, ESP_SPI_LEN) == 0) {
@@ -2248,7 +2248,7 @@ static int state_test_read_cb(const uint8_t *spi, uint32_t *oseq,
22482248
}
22492249

22502250
static int state_test_write_cb(const uint8_t *spi, uint32_t oseq,
2251-
uint32_t hi_seq, uint32_t bitmap)
2251+
uint32_t hi_seq, uint64_t bitmap)
22522252
{
22532253
state_write_calls++;
22542254
if (memcmp(spi, state_test_spi, ESP_SPI_LEN) == 0) {
@@ -2273,7 +2273,7 @@ state_test_wire_seq(const struct wolfIP_ip_packet *ip)
22732273
static uint8_t state_fail_spi[ESP_SPI_LEN] = {0x99, 0x88, 0x77, 0x66};
22742274

22752275
static int state_fail_read_cb(const uint8_t *spi, uint32_t *oseq,
2276-
uint32_t *hi_seq, uint32_t *bitmap)
2276+
uint32_t *hi_seq, uint64_t *bitmap)
22772277
{
22782278
if (memcmp(spi, state_fail_spi, ESP_SPI_LEN) == 0) {
22792279
*oseq = 0xDEADBEEFU;
@@ -2319,6 +2319,99 @@ START_TEST(test_esp_state_restore_failed_read_keeps_fresh_state)
23192319
}
23202320
END_TEST
23212321

2322+
/* F-11440: the persistence callbacks must carry the full 64-bit replay
2323+
* bitmap. The old uint32_t callback types truncated bits 32..63 on save
2324+
* and reconstituted only the lower half on restore, so a duplicate in
2325+
* the upper half of the window was accepted after a restore. */
2326+
static uint8_t state_64bit_spi[ESP_SPI_LEN] = {0x55, 0x44, 0x33, 0x22};
2327+
static uint32_t state64_oseq = 0;
2328+
static uint32_t state64_hi_seq = 0;
2329+
static uint64_t state64_bitmap = 0;
2330+
2331+
static int state64_read_cb(const uint8_t *spi, uint32_t *oseq,
2332+
uint32_t *hi_seq, uint64_t *bitmap)
2333+
{
2334+
if (memcmp(spi, state_64bit_spi, ESP_SPI_LEN) == 0) {
2335+
*oseq = state64_oseq;
2336+
*hi_seq = state64_hi_seq;
2337+
*bitmap = state64_bitmap;
2338+
return 0;
2339+
}
2340+
return -1; /* unknown SPI: start fresh */
2341+
}
2342+
2343+
static int state64_write_cb(const uint8_t *spi, uint32_t oseq,
2344+
uint32_t hi_seq, uint64_t bitmap)
2345+
{
2346+
if (memcmp(spi, state_64bit_spi, ESP_SPI_LEN) == 0) {
2347+
state64_oseq = oseq;
2348+
state64_hi_seq = hi_seq;
2349+
state64_bitmap = bitmap;
2350+
}
2351+
return 0;
2352+
}
2353+
2354+
START_TEST(test_esp_state_persistence_keeps_64bit_bitmap)
2355+
{
2356+
int ret;
2357+
wolfIP_esp_sa *esp_sa;
2358+
2359+
esp_setup();
2360+
state64_oseq = 0;
2361+
state64_hi_seq = 0;
2362+
state64_bitmap = 0;
2363+
2364+
ret = wolfIP_esp_state_set_cbs(state64_write_cb, state64_read_cb);
2365+
ck_assert_int_eq(ret, 0);
2366+
2367+
ret = wolfIP_esp_sa_new_cbc_hmac(1, state_64bit_spi,
2368+
atoip4(T_SRC), atoip4(T_DST),
2369+
(uint8_t *)k_aes128, sizeof(k_aes128),
2370+
ESP_AUTH_SHA256_RFC4868,
2371+
(uint8_t *)k_auth16, sizeof(k_auth16),
2372+
ESP_ICVLEN_HMAC_128);
2373+
ck_assert_int_eq(ret, 0);
2374+
esp_sa = esp_sa_get(1, state_64bit_spi);
2375+
ck_assert_ptr_nonnull(esp_sa);
2376+
2377+
/* A window with a set bit in the upper half of the bitmap:
2378+
* hi_seq 100, seq 60 already accepted (bit 100-60 = 40). */
2379+
esp_sa->replay.oseq = 7;
2380+
esp_sa->replay.hi_seq = 100;
2381+
esp_sa->replay.bitmap = (1ULL << 40) | 1ULL;
2382+
2383+
/* SA deletion is a save event: the write callback must receive the
2384+
* full 64-bit bitmap. */
2385+
wolfIP_esp_sa_del(1, state_64bit_spi);
2386+
ck_assert_uint_eq(state64_bitmap, (1ULL << 40) | 1ULL);
2387+
ck_assert_uint_eq(state64_hi_seq, 100U);
2388+
ck_assert_uint_eq(state64_oseq, 7U);
2389+
2390+
/* Recreating the SA must restore the full window, upper half
2391+
* included. */
2392+
ret = wolfIP_esp_sa_new_cbc_hmac(1, state_64bit_spi,
2393+
atoip4(T_SRC), atoip4(T_DST),
2394+
(uint8_t *)k_aes128, sizeof(k_aes128),
2395+
ESP_AUTH_SHA256_RFC4868,
2396+
(uint8_t *)k_auth16, sizeof(k_auth16),
2397+
ESP_ICVLEN_HMAC_128);
2398+
ck_assert_int_eq(ret, 0);
2399+
esp_sa = esp_sa_get(1, state_64bit_spi);
2400+
ck_assert_ptr_nonnull(esp_sa);
2401+
ck_assert_uint_eq(esp_sa->replay.bitmap, (1ULL << 40) | 1ULL);
2402+
ck_assert_uint_eq(esp_sa->replay.hi_seq, 100U);
2403+
ck_assert_uint_eq(esp_sa->replay.oseq, 7U);
2404+
2405+
/* The restored window must actually reject the upper-half duplicate
2406+
* (seq 60) and still accept new sequences. */
2407+
ck_assert_int_ne(esp_replay_check(&esp_sa->replay, 60U), 0);
2408+
ck_assert_int_eq(esp_replay_check(&esp_sa->replay, 101U), 0);
2409+
2410+
wolfIP_esp_sa_del_all();
2411+
wolfIP_esp_state_set_cbs(NULL, NULL);
2412+
}
2413+
END_TEST
2414+
23222415
START_TEST(test_esp_state_persistence_callbacks)
23232416
{
23242417
static uint8_t buf[LINK_MTU + 256];
@@ -2495,6 +2588,7 @@ static Suite *esp_suite(void)
24952588
tcase_add_test(tc, test_sa_del_all);
24962589
tcase_add_test(tc, test_esp_state_persistence_callbacks);
24972590
tcase_add_test(tc, test_esp_state_restore_failed_read_keeps_fresh_state);
2591+
tcase_add_test(tc, test_esp_state_persistence_keeps_64bit_bitmap);
24982592
suite_add_tcase(s, tc);
24992593

25002594
/* Replay window */

0 commit comments

Comments
 (0)