Skip to content

Commit 5abd3a8

Browse files
committed
Implemented hardening against spoofed local-ip packets
As suggested by copilot
1 parent 19a244b commit 5abd3a8

2 files changed

Lines changed: 52 additions & 2 deletions

File tree

src/test/unit/unit.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,51 @@ START_TEST(test_udp_recvfrom_null_addrlen)
12061206
}
12071207
END_TEST
12081208

1209+
START_TEST(test_udp_recvfrom_src_equals_local_ip_does_not_persist_remote)
1210+
{
1211+
struct wolfIP s;
1212+
int sd;
1213+
struct wolfIP_sockaddr_in sin;
1214+
uint8_t payload[4] = {0x01, 0x02, 0x03, 0x04};
1215+
uint8_t rxbuf[4] = {0};
1216+
struct wolfIP_sockaddr_in from;
1217+
socklen_t from_len = sizeof(from);
1218+
int ret;
1219+
ip4 local_ip = 0x0A000001U;
1220+
uint16_t local_port = 4005;
1221+
uint16_t remote_port = 5005;
1222+
struct tsocket *ts;
1223+
1224+
wolfIP_init(&s);
1225+
mock_link_init(&s);
1226+
wolfIP_ipconfig_set(&s, local_ip, 0xFFFFFF00U, 0);
1227+
1228+
sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_UDP);
1229+
ck_assert_int_gt(sd, 0);
1230+
1231+
memset(&sin, 0, sizeof(sin));
1232+
sin.sin_family = AF_INET;
1233+
sin.sin_port = ee16(local_port);
1234+
sin.sin_addr.s_addr = ee32(local_ip);
1235+
ret = wolfIP_sock_bind(&s, sd, (struct wolfIP_sockaddr *)&sin, sizeof(sin));
1236+
ck_assert_int_eq(ret, 0);
1237+
1238+
ts = &s.udpsockets[SOCKET_UNMARK(sd)];
1239+
ck_assert_uint_eq(ts->remote_ip, 0);
1240+
1241+
inject_udp_datagram(&s, TEST_PRIMARY_IF, local_ip, local_ip, remote_port, local_port,
1242+
payload, sizeof(payload));
1243+
1244+
memset(&from, 0, sizeof(from));
1245+
ret = wolfIP_sock_recvfrom(&s, sd, rxbuf, sizeof(rxbuf), 0,
1246+
(struct wolfIP_sockaddr *)&from, &from_len);
1247+
ck_assert_int_eq(ret, (int)sizeof(payload));
1248+
ck_assert_mem_eq(rxbuf, payload, sizeof(payload));
1249+
ck_assert_uint_eq(from.sin_addr.s_addr, ee32(local_ip));
1250+
ck_assert_uint_eq(ts->remote_ip, 0);
1251+
}
1252+
END_TEST
1253+
12091254
START_TEST(test_sock_error_paths)
12101255
{
12111256
struct wolfIP s;
@@ -12257,6 +12302,8 @@ Suite *wolf_suite(void)
1225712302
suite_add_tcase(s, tc_proto);
1225812303
tcase_add_test(tc_proto, test_udp_recvfrom_null_addrlen);
1225912304
suite_add_tcase(s, tc_proto);
12305+
tcase_add_test(tc_proto, test_udp_recvfrom_src_equals_local_ip_does_not_persist_remote);
12306+
suite_add_tcase(s, tc_proto);
1226012307
tcase_add_test(tc_proto, test_dns_query_and_callback_a);
1226112308
suite_add_tcase(s, tc_proto);
1226212309
tcase_add_test(tc_proto, test_dhcp_parse_offer_and_ack);

src/wolfip.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2656,8 +2656,11 @@ int wolfIP_sock_recvfrom(struct wolfIP *s, int sockfd, void *buf, size_t len, in
26562656
return -WOLFIP_EAGAIN;
26572657
desc = fifo_peek(&ts->sock.udp.rxbuf);
26582658
udp = (struct wolfIP_udp_datagram *)(ts->rxmem + desc->pos + sizeof(*desc));
2659-
if (ts->remote_ip == 0)
2660-
ts->remote_ip = ee32(udp->ip.src);
2659+
if (ts->remote_ip == 0) {
2660+
ip4 src_ip = ee32(udp->ip.src);
2661+
if (src_ip != ts->local_ip)
2662+
ts->remote_ip = src_ip;
2663+
}
26612664
if (sin) {
26622665
sin->sin_family = AF_INET;
26632666
sin->sin_port = ee16(udp->src_port);

0 commit comments

Comments
 (0)