From: Paul Donald Date: Tue, 4 Nov 2025 18:30:58 +0000 (+0100) Subject: dhcpv6: potential bug fix for checking DHCPV6_OPT_STATUS X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=a92f199d6b8d83e4779e884e49f9e516b3812669;p=project%2Fodhcp6c.git dhcpv6: potential bug fix for checking DHCPV6_OPT_STATUS follow-up to b65ff293a96924f9b19dff8855232bfb9054b976 The previous logic checked that the DHCPV6_OPT_STATUS was more than 2 bytes, which meant that it would only be evaluated if the options *also* contained a status message. We should handle this option being exactly 2 bytes, so that DHCPV6_OPT_STATUS lacking a status message are correctly handled. The relevant RFC section does not state that status message can be absent https://www.rfc-editor.org/rfc/rfc8415#section-21.13 but the status message field is variable length and sets no mandates on its size. This ensures differing interpretations of this portion are handled adequately. It's not uncommon that various options behave in this 'can be zero length' way, so let's handle this option similarly. Signed-off-by: Paul Donald Link: https://github.com/openwrt/odhcp6c/pull/113 Signed-off-by: Álvaro Fernández Rojas --- diff --git a/src/dhcpv6.c b/src/dhcpv6.c index 9c424ff..6aed871 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -1626,13 +1626,13 @@ static unsigned int dhcpv6_parse_ia(void *opt, void *end, int *ret) bool update_state = true; dhcpv6_for_each_option(odata + sizeof(*prefix) - 4U, odata + olen, stype, slen, sdata) { - if (stype == DHCPV6_OPT_STATUS && slen > 2) { + if (stype == DHCPV6_OPT_STATUS && slen >= 2) { /* RFC 8415 §21.22 The status of any operations involving this IA Prefix option is indicated in a Status Code option (see Section 21.13) in the IAprefix-options field. */ - uint8_t *status_msg = &sdata[2]; - uint16_t msg_len = slen - 2; + uint8_t *status_msg = (slen > 2) ? &sdata[2] : NULL; + uint16_t msg_len = (slen > 2) ? slen - 2 : 0; uint16_t code = ((int)sdata[0]) << 8 | ((int)sdata[1]); if (code == DHCPV6_Success) @@ -1709,13 +1709,13 @@ static unsigned int dhcpv6_parse_ia(void *opt, void *end, int *ret) bool update_state = true; dhcpv6_for_each_option(odata + sizeof(*addr) - 4U, odata + olen, stype, slen, sdata) { - if (stype == DHCPV6_OPT_STATUS && slen > 2) { + if (stype == DHCPV6_OPT_STATUS && slen >= 2) { /* RFC 8415 §21.6 The status of any operations involving this IA Address is indicated in a Status Code option in the IAaddr-options field, as specified in Section 21.13. */ - uint8_t *status_msg = &sdata[2]; - uint16_t msg_len = slen - 2; + uint8_t *status_msg = (slen > 2) ? &sdata[2] : NULL; + uint16_t msg_len = (slen > 2) ? slen - 2 : 0; uint16_t code = ((int)sdata[0]) << 8 | ((int)sdata[1]); if (code == DHCPV6_Success)