summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Fedoryshchenko <denys.f@collabora.com>2026-08-10 08:33:53 +0300
committerDenys Fedoryshchenko <denys.f@collabora.com>2026-08-10 08:33:53 +0300
commit52a01730fd02c2579f474c01ebf72a312f737825 (patch)
tree4b1a1ec3a7135ffaf1a66472412499762ef31035
parent6019e1d14937731be7c88628fc7c1253aaa701e7 (diff)
downloadaccel-ppp-52a01730fd02c2579f474c01ebf72a312f737825.tar.gz
accel-ppp-52a01730fd02c2579f474c01ebf72a312f737825.zip
dhcpv6: check option length before reading the status code
print_status() reads the 2-byte status code at offset 4 of the option, but parse_option() only guarantees that the option header plus its declared payload length are within the packet. A Status Code option with a payload length below 2 as the last option in a packet therefore made print_status() read past the end of the received buffer. Skip the option if its payload is too short to hold the code.
-rw-r--r--accel-pppd/ipv6/dhcpv6_packet.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/accel-pppd/ipv6/dhcpv6_packet.c b/accel-pppd/ipv6/dhcpv6_packet.c
index 9bdede95..e56d7b1d 100644
--- a/accel-pppd/ipv6/dhcpv6_packet.c
+++ b/accel-pppd/ipv6/dhcpv6_packet.c
@@ -534,7 +534,12 @@ static void print_status(struct dhcpv6_option *opt, void (*print)(const char *fm
"UseMulticast",
"NoPrefixAvail"
};
- unsigned int code = ntohs(o->code);
+ unsigned int code;
+
+ if ((unsigned int)ntohs(opt->hdr->len) < sizeof(o->code))
+ return;
+
+ code = ntohs(o->code);
if (code >= sizeof(status_name) / sizeof(status_name[0]))
print(" %u", code);