summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Fedoryshchenko <denys.f@collabora.com>2026-08-10 09:43:09 +0300
committerDenys Fedoryshchenko <denys.f@collabora.com>2026-08-10 09:43:09 +0300
commit7c98f320c3ef7e863a9c7d30bb81735bb4fec46d (patch)
tree53f8852abb971c96dcb03fb16c0eb5dd7ea2fc54
parentb0e7444cfea168b6b283ca89e00b57494e0bced2 (diff)
downloadaccel-ppp-7c98f320c3ef7e863a9c7d30bb81735bb4fec46d.tar.gz
accel-ppp-7c98f320c3ef7e863a9c7d30bb81735bb4fec46d.zip
dhcpv6: read the elapsed time and preference options at their real width
print_time() read a 32 bit word out of the Elapsed Time option, which RFC 8415 21.9 defines as exactly two octets, and clients include it in almost every message they send. With verbose enabled that is a two byte read past the option on every DHCPv6 transaction: ERROR: AddressSanitizer: heap-buffer-overflow READ of size 4 in print_time dhcpv6_packet.c:499 The value was not byte swapped either, so what got logged was not the elapsed time. Read two octets, convert them, and copy them out rather than dereferencing a pointer into the packet that need not be aligned. print_uint8() has the same shape, so check the length there too before reading the Preference octet.
-rw-r--r--accel-pppd/ipv6/dhcpv6_packet.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/accel-pppd/ipv6/dhcpv6_packet.c b/accel-pppd/ipv6/dhcpv6_packet.c
index 1cae30e6..c0c7bc81 100644
--- a/accel-pppd/ipv6/dhcpv6_packet.c
+++ b/accel-pppd/ipv6/dhcpv6_packet.c
@@ -498,12 +498,21 @@ static void print_hex_array(struct dhcpv6_option *opt, void (*print)(const char
static void print_uint8(struct dhcpv6_option *opt, void (*print)(const char *fmt, ...))
{
+ if (ntohs(opt->hdr->len) < sizeof(uint8_t))
+ return;
+
print(" %i", *(uint8_t *)opt->hdr->data);
}
static void print_time(struct dhcpv6_option *opt, void (*print)(const char *fmt, ...))
{
- print(" %u", *(uint32_t *)opt->hdr->data);
+ uint16_t val;
+
+ if (ntohs(opt->hdr->len) < sizeof(val))
+ return;
+
+ memcpy(&val, opt->hdr->data, sizeof(val));
+ print(" %u", ntohs(val));
}
static void print_ipv6addr(struct dhcpv6_option *opt, void (*print)(const char *fmt, ...))