diff options
-rw-r--r-- | sbin/dhclient/options.c | 34 |
1 files changed, 18 insertions, 16 deletions
diff --git a/sbin/dhclient/options.c b/sbin/dhclient/options.c index ac816f5d452..6d2eb78c76b 100644 --- a/sbin/dhclient/options.c +++ b/sbin/dhclient/options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: options.c,v 1.40 2012/06/26 14:36:11 krw Exp $ */ +/* $OpenBSD: options.c,v 1.41 2012/06/26 14:46:42 krw Exp $ */ /* DHCP options parsing and reassembly. */ @@ -68,21 +68,23 @@ parse_option_buffer(struct option_data *options, unsigned char *buffer, } /* - * All options other than DHO_PAD and DHO_END have a - * one-byte length field. + * All options other than DHO_PAD and DHO_END have a one-byte + * length field. It could be 0! Make sure that the length byte + * is present, and all the data is available. */ - if (s + 2 > end) - len = 0; - else + if (s + 1 < end) { len = s[1]; - - /* - * If the option claims to extend beyond the end of the buffer - * then mark the options buffer bad. - */ - if (s + len + 2 > end) { - warning("option %s (%d) larger than buffer.", - dhcp_options[code].name, len); + if (s + 1 + len < end) { + ; /* option data is all there. */ + } else { + warning("option %s (%d) larger than buffer.", + dhcp_options[code].name, len); + warning("rejecting bogus offer."); + return (0); + } + } else { + warning("option %s has no length field.", + dhcp_options[code].name); warning("rejecting bogus offer."); return (0); } @@ -95,8 +97,8 @@ parse_option_buffer(struct option_data *options, unsigned char *buffer, * MUST be prepared to delete trailing nulls if they exist." */ if (dhcp_options[code].format[0] == 't') { - for (len = s[1]; len > 0 && s[len + 1] == '\0'; len--) - ; + while (len > 0 && s[len + 1] == '\0') + len--; } /* |