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 /* 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;