CVS commit: [netbsd-4-0] src/dist/dhcp/client

2011-04-07 Thread Jeff Rizzo
Module Name:src
Committed By:   riz
Date:   Thu Apr  7 17:33:17 UTC 2011

Modified Files:
src/dist/dhcp/client [netbsd-4-0]: dhclient.c

Log Message:
Pull up following revision(s) (requested by christos in ticket #1427):
dist/dhcp/client/dhclient.c: revision 1.21
CVE-2011-0997 dhclient: insufficient sanitization of certain DHCP
response values. Apply patch by hand from the 3.1-ESV-R1 release.


To generate a diff of this commit:
cvs rdiff -u -r1.18.12.1 -r1.18.12.2 src/dist/dhcp/client/dhclient.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/dist/dhcp/client/dhclient.c
diff -u src/dist/dhcp/client/dhclient.c:1.18.12.1 src/dist/dhcp/client/dhclient.c:1.18.12.2
--- src/dist/dhcp/client/dhclient.c:1.18.12.1	Tue Jul 14 19:57:00 2009
+++ src/dist/dhcp/client/dhclient.c	Thu Apr  7 17:33:17 2011
@@ -32,7 +32,7 @@
 
 #ifndef lint
 static char ocopyright[] =
-"$Id: dhclient.c,v 1.18.12.1 2009/07/14 19:57:00 snj Exp $ Copyright (c) 2004-2005 Internet Systems Consortium.  All rights reserved.\n";
+"$Id: dhclient.c,v 1.18.12.2 2011/04/07 17:33:17 riz Exp $ Copyright (c) 2004-2005 Internet Systems Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #include "dhcpd.h"
@@ -79,6 +79,11 @@
 static void usage PROTO ((void));
 static void limit_interval PROTO((struct client_state *));
 
+static int check_domain_name(const char *ptr, size_t len, int dots);
+static int check_domain_name_list(const char *ptr, size_t len, int dots);
+static int check_option_values(struct universe *universe, unsigned int opt,
+			   const char *ptr, size_t len);
+
 void do_release(struct client_state *);
 
 #if !defined (SMALL)
@@ -2476,12 +2481,23 @@
 			char name [256];
 			if (dhcp_option_ev_name (name, sizeof name,
 		 oc -> option)) {
-client_envadd (es -> client, es -> prefix,
-	   name, "%s",
-	   (pretty_print_option
-		(oc -> option,
-		 data.data, data.len,
-		 0, 0)));
+const char *value;
+value = pretty_print_option(oc->option,
+			data.data,
+			data.len, 0, 0);
+size_t length = strlen(value);
+
+if (check_option_values(oc->option->universe,
+			oc->option->code,
+			value, length) == 0) {
+	client_envadd(es->client, es->prefix,
+		  name, "%s", value);
+} else {
+	log_error("suspect value in %s "
+		  "option - discarded",
+		  name);
+}
+
 data_string_forget (&data, MDL);
 			}
 		}
@@ -2554,13 +2570,31 @@
 		data_string_forget (&data, MDL);
 	}
 
-	if (lease -> filename)
-		client_envadd (client,
-			   prefix, "filename", "%s", lease -> filename);
-	if (lease -> server_name)
-		client_envadd (client, prefix, "server_name",
-			   "%s", lease -> server_name);
+	if (lease->filename) {
+		if (check_option_values(NULL, DHO_ROOT_PATH,
+	lease->filename,
+	strlen(lease->filename)) == 0) {
+			client_envadd(client, prefix, "filename",
+  "%s", lease->filename);
+		} else {
+			log_error("suspect value in %s "
+  "option - discarded",
+  lease->filename);
+		}
+	}
 
+	if (lease->server_name) {
+		if (check_option_values(NULL, DHO_HOST_NAME,
+	lease->server_name,
+	strlen(lease->server_name)) == 0 ) {
+			client_envadd (client, prefix, "server_name",
+   "%s", lease->server_name);
+		} else {
+			log_error("suspect value in %s "
+  "option - discarded",
+  lease->server_name);
+		}
+	}
 	for (i = 0; i < lease -> options -> universe_count; i++) {
 		option_space_foreach ((struct packet *)0, (struct lease *)0,
   client, (struct option_state *)0,
@@ -3185,3 +3219,115 @@
 #endif
 	return rcode;
 }
+
+/*
+ * The following routines are used to check that certain
+ * strings are reasonable before we pass them to the scripts.
+ * This avoids some problems with scripts treating the strings
+ * as commands - see ticket 23722
+ * The domain checking code should be done as part of assembling
+ * the string but we are doing it here for now due to time
+ * constraints.
+ */
+
+static int check_domain_name(const char *ptr, size_t len, int dots)
+{
+	const char *p;
+
+	/* not empty or complete length not over 255 characters   */
+	if ((len == 0) || (len > 256))
+		return(-1);
+
+	/* consists of [[:alnum:]-]+ labels separated by [.]  */
+	/* a [_] is against RFC but seems to be "widely used"...  */
+	for (p=ptr; (*p != 0) && (len-- > 0); p++) {
+		if ((*p == '-') || (*p == '_')) {
+			/* not allowed at begin or end of a label */
+			if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
+return(-1);
+		} else if (*p == '.') {
+			/* each label has to be 1-63 characters;
+			   we allow [.] at the end ('foo.bar.')   */
+			size_t d = p - ptr;
+			if ((d <= 0) || (d >= 64))
+return(-1);
+			ptr = p + 1; /* jump to the next label*/
+			if ((dots > 0) && (len > 0))
+dots--;
+		} else if (isalnum((unsigned char)*p) == 0) {
+			/* al

CVS commit: [netbsd-4-0] src/dist/dhcp/client

2009-07-14 Thread Soren Jacobsen
Module Name:src
Committed By:   snj
Date:   Tue Jul 14 19:57:00 UTC 2009

Modified Files:
src/dist/dhcp/client [netbsd-4-0]: dhclient.c

Log Message:
Pull up following revision(s) (requested by tonnerre in ticket #1336):
dist/dhcp/client/dhclient.c: revision 1.20
Limit the length of the address mask before we copy it.


To generate a diff of this commit:
cvs rdiff -u -r1.18 -r1.18.12.1 src/dist/dhcp/client/dhclient.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/dist/dhcp/client/dhclient.c
diff -u src/dist/dhcp/client/dhclient.c:1.18 src/dist/dhcp/client/dhclient.c:1.18.12.1
--- src/dist/dhcp/client/dhclient.c:1.18	Sat Oct  7 14:14:06 2006
+++ src/dist/dhcp/client/dhclient.c	Tue Jul 14 19:57:00 2009
@@ -32,7 +32,7 @@
 
 #ifndef lint
 static char ocopyright[] =
-"$Id: dhclient.c,v 1.18 2006/10/07 14:14:06 tron Exp $ Copyright (c) 2004-2005 Internet Systems Consortium.  All rights reserved.\n";
+"$Id: dhclient.c,v 1.18.12.1 2009/07/14 19:57:00 snj Exp $ Copyright (c) 2004-2005 Internet Systems Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #include "dhcpd.h"
@@ -2521,6 +2521,8 @@
 		if (data.len > 3) {
 			struct iaddr netmask, subnet, broadcast;
 
+			if (data.len > sizeof netmask.iabuf)
+			data.len = sizeof netmask.iabuf;
 			memcpy (netmask.iabuf, data.data, data.len);
 			netmask.len = data.len;
 			data_string_forget (&data, MDL);