Synopsis: dhclient vulnerability
NetBSD versions: NetBSD 1.4, 1.4.1, and 1.4.2
Thanks to: Todd Fries, Itojun, Ted Lemon
Reported in NetBSD Security Advisory: SA2000-008
--- usr.sbin/dhcp/common/options.c.orig 1999/03/30 03:10:46 1.1.1.9
+++ usr.sbin/dhcp/common/options.c 2000/06/28 18:47:02 1.1.1.9.2.1
@@ -47,6 +47,7 @@
#define DHCP_OPTION_DATA
#include "dhcpd.h"
+#include <ctype.h>
/* Parse all available options out of the specified packet. */
@@ -439,7 +440,7 @@
int numhunk = -1;
int numelem = 0;
char fmtbuf [32];
- int i, j;
+ int i, j, k;
char *op = optbuf;
unsigned char *dp = data;
struct in_addr foo;
@@ -471,11 +472,21 @@
numhunk = 0;
break;
case 'X':
- fmtbuf [i] = 'x';
+ for (k = 0; k < len; k++) {
+ if (!isascii (data [k]) ||
+ !isprint (data [k]))
+ break;
+ }
+ if (k == len) {
+ fmtbuf [i] = 't';
+ numhunk = -2;
+ } else {
+ fmtbuf [i] = 'x';
+ hunksize++;
+ comma = ':';
+ numhunk = 0;
+ }
fmtbuf [i + 1] = 0;
- hunksize++;
- numhunk = 0;
- comma = ':';
break;
case 't':
fmtbuf [i] = 't';
@@ -539,8 +550,22 @@
case 't':
if (emit_quotes)
*op++ = '"';
- strcpy (op, (char *)dp);
- op += strlen ((char *)dp);
+ for (; dp < data + len; dp++) {
+ if (!isascii (*dp) ||
+ !isprint (*dp)) {
+ sprintf (op, "\\%03o",
+ *dp);
+ op += 4;
+ } else if (*dp == '"' ||
+ *dp == '\'' ||
+ *dp == '$' ||
+ *dp == '`' ||
+ *dp == '\\') {
+ *op++ = '\\';
+ *op++ = *dp;
+ } else
+ *op++ = *dp;
+ }
if (emit_quotes)
*op++ = '"';
*op = 0;