Skip to content

Commit f7263c9

Browse files
committed
DHCP offer and ACK: validate xid
F/692
1 parent d1307b4 commit f7263c9

2 files changed

Lines changed: 69 additions & 0 deletions

File tree

src/test/unit/unit.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8789,6 +8789,69 @@ START_TEST(test_dhcp_parse_ack_missing_end_rejected)
87898789
}
87908790
END_TEST
87918791

8792+
START_TEST(test_dhcp_parse_offer_rejects_mismatched_xid)
8793+
{
8794+
struct wolfIP s;
8795+
struct dhcp_msg msg;
8796+
struct dhcp_option *opt;
8797+
struct ipconf *primary;
8798+
8799+
wolfIP_init(&s);
8800+
primary = wolfIP_primary_ipconf(&s);
8801+
ck_assert_ptr_nonnull(primary);
8802+
s.dhcp_xid = 0x12345678U;
8803+
8804+
memset(&msg, 0, sizeof(msg));
8805+
msg.magic = ee32(DHCP_MAGIC);
8806+
msg.xid = ee32(0x87654321U);
8807+
msg.yiaddr = ee32(0x0A000064U);
8808+
opt = (struct dhcp_option *)msg.options;
8809+
opt->code = DHCP_OPTION_MSG_TYPE;
8810+
opt->len = 1;
8811+
opt->data[0] = DHCP_OFFER;
8812+
opt = (struct dhcp_option *)((uint8_t *)opt + 3);
8813+
opt->code = DHCP_OPTION_END;
8814+
opt->len = 0;
8815+
8816+
ck_assert_int_eq(dhcp_parse_offer(&s, &msg, sizeof(msg)), -1);
8817+
ck_assert_uint_eq(s.dhcp_ip, 0U);
8818+
ck_assert_uint_eq(primary->ip, 0U);
8819+
ck_assert_int_eq(s.dhcp_state, DHCP_OFF);
8820+
}
8821+
END_TEST
8822+
8823+
START_TEST(test_dhcp_parse_ack_rejects_mismatched_xid)
8824+
{
8825+
struct wolfIP s;
8826+
struct dhcp_msg msg;
8827+
struct dhcp_option *opt;
8828+
struct ipconf *primary;
8829+
8830+
wolfIP_init(&s);
8831+
primary = wolfIP_primary_ipconf(&s);
8832+
ck_assert_ptr_nonnull(primary);
8833+
s.dhcp_xid = 0x12345678U;
8834+
s.dhcp_ip = 0x0A000064U;
8835+
s.dhcp_server_ip = 0x0A000001U;
8836+
s.dhcp_state = DHCP_REQUEST_SENT;
8837+
8838+
memset(&msg, 0, sizeof(msg));
8839+
msg.magic = ee32(DHCP_MAGIC);
8840+
msg.xid = ee32(0x87654321U);
8841+
opt = (struct dhcp_option *)msg.options;
8842+
opt->code = DHCP_OPTION_MSG_TYPE;
8843+
opt->len = 1;
8844+
opt->data[0] = DHCP_ACK;
8845+
opt = (struct dhcp_option *)((uint8_t *)opt + 3);
8846+
opt->code = DHCP_OPTION_END;
8847+
opt->len = 0;
8848+
8849+
ck_assert_int_eq(dhcp_parse_ack(&s, &msg, sizeof(msg)), -1);
8850+
ck_assert_int_eq(s.dhcp_state, DHCP_REQUEST_SENT);
8851+
ck_assert_uint_eq(primary->ip, 0U);
8852+
}
8853+
END_TEST
8854+
87928855
START_TEST(test_dhcp_parse_offer_bad_magic_rejected)
87938856
{
87948857
struct wolfIP s;
@@ -19620,6 +19683,8 @@ Suite *wolf_suite(void)
1962019683
tcase_add_test(tc_proto, test_dns_query_and_callback_a);
1962119684
tcase_add_test(tc_proto, test_dhcp_parse_offer_and_ack);
1962219685
tcase_add_test(tc_proto, test_dhcp_parse_offer_defaults_mask_when_missing);
19686+
tcase_add_test(tc_proto, test_dhcp_parse_offer_rejects_mismatched_xid);
19687+
tcase_add_test(tc_proto, test_dhcp_parse_ack_rejects_mismatched_xid);
1962319688
tcase_add_test(tc_proto, test_tcp_handshake_and_fin_close_wait);
1962419689

1962519690
tcase_add_test(tc_proto, test_regression_snd_una_initialized_on_syn_rcvd);

src/wolfip.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4939,6 +4939,8 @@ static int dhcp_parse_offer(struct wolfIP *s, struct dhcp_msg *msg, uint32_t msg
49394939
return -1;
49404940
if (ee32(msg->magic) != DHCP_MAGIC)
49414941
return -1;
4942+
if (ee32(msg->xid) != s->dhcp_xid)
4943+
return -1;
49424944
if (msg_len - DHCP_HEADER_LEN > sizeof(msg->options))
49434945
opt_end = (uint8_t *)msg->options + sizeof(msg->options);
49444946
else
@@ -5034,6 +5036,8 @@ static int dhcp_parse_ack(struct wolfIP *s, struct dhcp_msg *msg, uint32_t msg_l
50345036
return -1;
50355037
if (ee32(msg->magic) != DHCP_MAGIC)
50365038
return -1;
5039+
if (ee32(msg->xid) != s->dhcp_xid)
5040+
return -1;
50375041
if (msg_len - DHCP_HEADER_LEN > sizeof(msg->options))
50385042
opt_end = (uint8_t *)msg->options + sizeof(msg->options);
50395043
else

0 commit comments

Comments
 (0)