From ab346ea93dac7738860632ff6089394434babc49 Mon Sep 17 00:00:00 2001 From: David Hankins Date: Tue, 1 Nov 2005 23:19:03 +0000 Subject: - Changes to trailing NULL removal in 't' option-atoms has been rethought, it now includes 'd' (domain name) types, and tries hard not to rewind an option beyond the start of the text field it is un-terminating. [ISC-Bugs #15561] - 'T' DHCP atom documented. --- common/options.c | 55 +++++++++++++++++++++++++++++-------------------------- common/tables.c | 5 ++++- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/common/options.c b/common/options.c index 7537d826..401bcd23 100644 --- a/common/options.c +++ b/common/options.c @@ -34,7 +34,7 @@ #ifndef lint static char copyright[] = -"$Id: options.c,v 1.85.2.31 2005/10/27 16:00:18 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n"; +"$Id: options.c,v 1.85.2.32 2005/11/01 23:19:03 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n"; #endif /* not lint */ #define DHCP_OPTION_DATA @@ -1057,7 +1057,7 @@ format_has_text(format) p = format; while (*p != '\0') { - switch (*p) { + switch (*p++) { case 'd': case 't': return 1; @@ -1080,8 +1080,7 @@ format_has_text(format) */ case 'E': case 'N': - /* Skip to after trailing . after name. */ - p++; + /* Consume the space name. */ while ((*p != '\0') && (*p++ != '.')) ; break; @@ -1089,8 +1088,6 @@ format_has_text(format) default: break; } - - p++; } return 0; @@ -1113,11 +1110,11 @@ format_min_length(format, oc) p = format; while (*p != '\0') { - switch (*p) { + switch (*p++) { case 'I': /* IPv4 Address */ case 'l': /* int32_t */ case 'L': /* uint32_t */ - case 'T': /* Time, I think. (undocumented) */ + case 'T': /* Lease Time, uint32_t equivalent */ min_len += 4; last_size = 4; break; @@ -1129,10 +1126,12 @@ format_min_length(format, oc) break; case 'N': /* Enumeration in 1-byte values. */ - /* Skip the enumeration space name. */ - p++; + /* Consume space name. */ while ((*p != '\0') && (*p++ != '.')) ; + + /* Fall Through to handle as one-byte field */ + case 'b': /* int8_t */ case 'B': /* uint8_t */ case 'F': /* Flag that is always true. */ @@ -1148,16 +1147,13 @@ format_min_length(format, oc) break; case 'E': /* Encapsulated options. */ - /* Skip to after the trailing dot after the - * encapsulation name. - */ - p++; + /* Consume space name. */ while ((*p != '\0') && (*p++ != '.')) - ; /* This space intentionally left blank. */ + ; /* Find an end option, or find that the encaps options - * go all the way to the end of the data portion of - * the option. + * go all the way to the end (or beyond) of the data + * portion of the option. */ last_size = 0; while (min_len < oc->data.len) { @@ -1169,17 +1165,26 @@ format_min_length(format, oc) min_len++; last_size++; } else if ((min_len + 1) < oc->data.len) { - min_len += oc->data.data[min_len + 1]; - last_size += oc->data.data[min_len + 1]; + min_len += oc->data.data[min_len+1]+2; + last_size += oc->data.data[min_len+1]+2; } else { - log_error("format_min_length(%s): " - "Encapsulated options " - "exceed supplied buffer.", - format); - return INT_MAX; + /* Suboption length is out of bounds, + * advance beyond the code/length pair + * to trigger below error conditonal. + */ + min_len += 2; + last_size += 2; + break; } } + if (min_len > oc->data.len) { + log_error("format_min_length(%s): " + "Encapsulated options exceed " + "supplied buffer.", format); + return INT_MAX; + } + break; case 'd': /* "Domain name" */ @@ -1196,8 +1201,6 @@ format_min_length(format, oc) "for unknown format symbols.", format); return INT_MAX; } - - p++; } return min_len; diff --git a/common/tables.c b/common/tables.c index 204ed840..2b20c772 100644 --- a/common/tables.c +++ b/common/tables.c @@ -34,7 +34,7 @@ #ifndef lint static char copyright[] = -"$Id: tables.c,v 1.51.2.10 2005/08/26 22:45:46 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n"; +"$Id: tables.c,v 1.51.2.11 2005/11/01 23:19:03 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -58,6 +58,9 @@ HASH_FUNCTIONS (option, const char *, struct option, option_hash_t, 0, 0) b - 8-bit signed integer B - 8-bit unsigned integer t - ASCII text + T - Lease Time, 32-bit unsigned integer implying a number of seconds from + some event. The special all-ones value means 'infinite'. May either + be printed as a decimal, eg, "3600", or as this name, eg, "infinite". f - flag (true or false) A - array of whatever precedes (e.g., IA means array of IP addresses) a - array of the preceding character (e.g., IIa means two or more IP -- cgit v1.2.1