summaryrefslogtreecommitdiff
path: root/sbin/dhclient/options.c
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2012-06-26 14:46:43 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2012-06-26 14:46:43 +0000
commitd14eab152633551a34c3058feb21fd6030c5a822 (patch)
tree28700162c335e79ac0d9cb4ab68b89a746ae62d3 /sbin/dhclient/options.c
parent0132a36e35e62ab24249e7dcd0deb2fa716168ce (diff)
Add some more paranoia and make code clearer. Check that the required
length field for the option is present before using it. Reject lease if no length field is present.
Diffstat (limited to 'sbin/dhclient/options.c')
-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--;
}
/*