From 6019e1d14937731be7c88628fc7c1253aaa701e7 Mon Sep 17 00:00:00 2001 From: Denys Fedoryshchenko Date: Mon, 10 Aug 2026 08:32:47 +0300 Subject: dhcpv6: fix status code name table and its bounds check A missing comma made "UseMulticast" and "NoPrefixAvail" concatenate into a single string literal, so the table held 6 entries instead of 7: UseMulticast printed as "UseMulticastNoPrefixAvail" and NoPrefixAvail had no entry at all. The bounds check compared the status code against sizeof(status_name), which is the size of the table in bytes (48), not its number of entries. Codes 6..48 passed the check and indexed past the end of the table, so print() was handed whatever pointer-sized garbage followed it. A client can trigger this by sending a Status Code option with an out-of-range code, which is printed verbatim when verbose is enabled. Compare against the entry count instead, and drop the ntohs() < 0 test, which can never be true for an unsigned value. --- accel-pppd/ipv6/dhcpv6_packet.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/accel-pppd/ipv6/dhcpv6_packet.c b/accel-pppd/ipv6/dhcpv6_packet.c index e0f2b5d9..9bdede95 100644 --- a/accel-pppd/ipv6/dhcpv6_packet.c +++ b/accel-pppd/ipv6/dhcpv6_packet.c @@ -531,14 +531,15 @@ static void print_status(struct dhcpv6_option *opt, void (*print)(const char *fm "NoAddrsAvail", "NoBindings", "NotOnLink", - "UseMulticast" + "UseMulticast", "NoPrefixAvail" }; + unsigned int code = ntohs(o->code); - if (ntohs(o->code) < 0 || ntohs(o->code) > sizeof(status_name)) - print(" %u", ntohs(o->code)); + if (code >= sizeof(status_name) / sizeof(status_name[0])) + print(" %u", code); else - print(" %s", status_name[ntohs(o->code)]); + print(" %s", status_name[code]); } static void print_reconf(struct dhcpv6_option *opt, void (*print)(const char *fmt, ...)) -- cgit v1.2.3