blob: 70a80013537580131bb9724cd7b4b227a266abeb [file] [log] [blame]
From cbedd9f8473e7fec3571a8d5f4e9bafdfd0c9d87 Mon Sep 17 00:00:00 2001
From: Jorge Lucangeli Obes <jorgelo@chromium.org>
Date: Wed, 13 May 2015 16:26:56 -0700
Subject: [PATCH] Fix OOB read in dhcpcd.
Should have done this sooner, but hey, late is better than never.
Based on https://googleplex-android-review.git.corp.google.com/#/c/588010/.
BUG=chromium:433078
TEST=Deploy to Chromebook, connect to network, get DHCP lease.
Reviewed-on: https://chromium-review.googlesource.com/242880
---
dhcp-common.c | 4 ++++
dhcp.c | 8 ++++++--
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/dhcp-common.c b/dhcp-common.c
index 39d9787..05d2cdb 100644
--- a/dhcp-common.c
+++ b/dhcp-common.c
@@ -722,6 +722,10 @@ print_option(char *s, size_t len, int type, const uint8_t *data, size_t dl,
#endif
else
sl = 0;
+ if (len <= sl) {
+ bytes += len;
+ break;
+ }
len -= (size_t)sl;
bytes += sl;
s += sl;
diff --git a/dhcp.c b/dhcp.c
index 8fca2f6..dfc2a30 100644
--- a/dhcp.c
+++ b/dhcp.c
@@ -166,7 +166,11 @@ get_option(struct dhcpcd_ctx *ctx,
return NULL;
}
- while (p < e) {
+ /* DHCP options are in TLV format with T and L each being a single
+ * bytes. In general, here we have p -> T, ol=p+1 -> L, op -> V.
+ * We must make sure there is enough room to read both T and L.
+ */
+ while (p + 1 < e) {
o = *p++;
if (o == opt) {
if (op) {
@@ -182,7 +186,7 @@ get_option(struct dhcpcd_ctx *ctx,
memcpy(bp, op, ol);
bp += ol;
}
- ol = *p;
+ ol = (p + *p < e) ? *p : e - (p + 1);
if (p + ol > e) {
errno = EINVAL;
return NULL;
--
2.2.0.rc0.207.ga3a616c