Skip to content

Commit

Permalink
sd-dhcp6-client: fix off-by-one error in parsing dhcp6 options
Browse files Browse the repository at this point in the history
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 68870a4)
  • Loading branch information
yuwata authored and keszybz committed Aug 8, 2022
1 parent 3561039 commit 2a674b4
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/libsystemd-network/dhcp6-option.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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;
Expand Down
42 changes: 42 additions & 0 deletions src/libsystemd-network/test-dhcp6-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 2a674b4

Please sign in to comment.