1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-22 22:03:43 +03:00

sd-dhcp6-client: fix off-by-one error in parsing dhcp6 options

This fixes error in parsing message when the rapid commit option is
located at the end of the message.

Fixes an issure reported in #24002.

(cherry picked from commit 68870a46b3b5d3d5b51d1c27b4128b8fb5188ecb)
This commit is contained in:
Yu Watanabe 2022-07-14 09:23:09 +09:00 committed by Zbigniew Jędrzejewski-Szmek
parent 35610398d7
commit 2a674b4b66
2 changed files with 44 additions and 2 deletions

View File

@ -508,7 +508,7 @@ int dhcp6_option_parse(
if (buflen < offsetof(DHCP6Option, data))
return -EBADMSG;
if (*offset >= buflen - offsetof(DHCP6Option, data))
if (*offset > buflen - offsetof(DHCP6Option, data))
return -EBADMSG;
len = unaligned_read_be16(buf + *offset + offsetof(DHCP6Option, len));
@ -518,7 +518,7 @@ int dhcp6_option_parse(
*ret_option_code = unaligned_read_be16(buf + *offset + offsetof(DHCP6Option, code));
*ret_option_data_len = len;
*ret_option_data = buf + *offset + offsetof(DHCP6Option, data);
*ret_option_data = len == 0 ? NULL : buf + *offset + offsetof(DHCP6Option, data);
*offset += offsetof(DHCP6Option, data) + len;
return 0;

View File

@ -443,6 +443,48 @@ TEST(client_parse_message_issue_22099) {
assert_se(dhcp6_lease_new_from_message(client, (const DHCP6Message*) msg, sizeof(msg), NULL, NULL, &lease) >= 0);
}
TEST(client_parse_message_issue_24002) {
static const uint8_t msg[] = {
/* Message Type */
0x07,
/* Transaction ID */
0x0e, 0xa5, 0x7c,
/* Client ID */
0x00, SD_DHCP6_OPTION_CLIENTID, 0x00, 0x0e,
0x00, 0x02, /* DUID-EN */
0x00, 0x00, 0xab, 0x11, /* pen */
0x5c, 0x6b, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, /* id */
/* Server ID */
0x00, 0x02, 0x00, 0x1a,
0x00, 0x02, 0x00, 0x00, 0x05, 0x83, 0x30, 0x63, 0x3a, 0x38, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
/* IA_PD */
0x00, 0x19, 0x00, 0x29,
0xaa, 0xbb, 0xcc, 0xdd, /* iaid */
0x00, 0x00, 0x03, 0x84, /* lifetime (T1) */
0x00, 0x00, 0x05, 0xa0, /* lifetime (T2) */
/* IA_PD (iaprefix suboption) */
0x00, 0x1a, 0x00, 0x19,
0x00, 0x00, 0x07, 0x08, /* preferred lifetime */
0x00, 0x00, 0x38, 0x40, /* valid lifetime */
0x38, /* prefixlen */
0x20, 0x03, 0x00, 0xff, 0xaa, 0xbb, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* prefix */
/* Rapid commit */
0x00, 0x0e, 0x00, 0x00,
};
static const uint8_t duid[] = {
0x00, 0x00, 0xab, 0x11, 0x5c, 0x6b, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
};
_cleanup_(sd_dhcp6_client_unrefp) sd_dhcp6_client *client = NULL;
_cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
assert_se(sd_dhcp6_client_new(&client) >= 0);
assert_se(sd_dhcp6_client_set_iaid(client, 0xaabbccdd) >= 0);
assert_se(sd_dhcp6_client_set_duid(client, 2, duid, sizeof(duid)) >= 0);
assert_se(dhcp6_lease_new_from_message(client, (const DHCP6Message*) msg, sizeof(msg), NULL, NULL, &lease) >= 0);
}
static const uint8_t msg_information_request[] = {
/* Message type */
DHCP6_MESSAGE_INFORMATION_REQUEST,