summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/dhclient/options.c34
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--;
}
/*