aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Senior <russell@personaltelco.net>2021-03-15 22:42:43 -0700
committerDenys Vlasenko <vda.linux@googlemail.com>2021-03-16 11:40:19 +0100
commit1c461df70ab357dc9e1e064540731c58e7859a45 (patch)
treed2308f480013701e3abb19584244525f89bca66d
parentf26e5634b161e58f56b072f6e703f262e723a80d (diff)
downloadbusybox-w32-1c461df70ab357dc9e1e064540731c58e7859a45.tar.gz
busybox-w32-1c461df70ab357dc9e1e064540731c58e7859a45.tar.bz2
busybox-w32-1c461df70ab357dc9e1e064540731c58e7859a45.zip
udhcpc: ignore zero-length DHCP options
Discovered that the DHCP server on a TrendNet router (unknown model) provides a zero-length option 12 (Host Name) in the DHCP ACK message. This has the effect of causing udhcpc to drop the rest of the options, including option 51 (IP Address Lease Time), 3 (Router), and 6 (Domain Name Server), most importantly leaving the OpenWrt device with no default gateway. The TrendNet behavior violates RFC 2132, which in Section 3.14 declares that option 12 has a minimum length of 1 octet. It is perhaps not a cosmic coincidence that I found this behavior on Pi Day. This patch allows zero length options without bailing out, by simply skipping them. function old new delta udhcp_scan_options 183 172 -11 Signed-off-by: Russell Senior <russell@personaltelco.net> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/udhcp/common.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c
index 4bc719001..99ecb7aa6 100644
--- a/networking/udhcp/common.c
+++ b/networking/udhcp/common.c
@@ -273,17 +273,27 @@ uint8_t* FAST_FUNC udhcp_scan_options(struct dhcp_packet *packet, struct dhcp_sc
273 break; 273 break;
274 } 274 }
275 275
276 if (scan_state->rem <= OPT_LEN) 276 if (scan_state->rem <= OPT_LEN) /* [len] byte exists? */
277 goto complain; /* complain and return NULL */ 277 goto complain; /* no, complain and return NULL */
278 len = 2 + scan_state->optionptr[OPT_LEN]; 278 len = scan_state->optionptr[OPT_LEN];
279 /* Skip options with zero length.
280 * Users report that DHCP server on a TrendNet router (unknown model)
281 * provides a zero-length option 12 (Host Name)
282 * (this violates RFC 2132 section 3.14).
283 */
284 if (len == 0) {
285 scan_state->rem -= OPT_LEN;
286 scan_state->optionptr += OPT_LEN;
287 continue;
288 }
289 len += OPT_LEN;
279 scan_state->rem -= len; 290 scan_state->rem -= len;
280 /* So far no valid option with length 0 known. */ 291 if (scan_state->rem < 0) /* option is longer than options field? */
281 if (scan_state->rem < 0 || scan_state->optionptr[OPT_LEN] == 0) 292 goto complain; /* yes, complain and return NULL */
282 goto complain; /* complain and return NULL */
283 293
284 if (scan_state->optionptr[OPT_CODE] == DHCP_OPTION_OVERLOAD) { 294 if (scan_state->optionptr[OPT_CODE] == DHCP_OPTION_OVERLOAD) {
285 if (len >= 3) 295 /* len is known to be >= 3 now, [data] byte exists */
286 scan_state->overload |= scan_state->optionptr[OPT_DATA]; 296 scan_state->overload |= scan_state->optionptr[OPT_DATA];
287 } else { 297 } else {
288 uint8_t *return_ptr = scan_state->optionptr; 298 uint8_t *return_ptr = scan_state->optionptr;
289 scan_state->optionptr += len; 299 scan_state->optionptr += len;