svn commit: r193765 - head/sbin/dhclient

Brian Somers brian at FreeBSD.org
Mon Jun 8 21:42:31 UTC 2009


Author: brian
Date: Mon Jun  8 21:42:30 2009
New Revision: 193765
URL: http://svn.freebsd.org/changeset/base/193765

Log:
  Fix an off by one error when we limit append/prepend text sizes based on our
  internal buffer sizes.
  
  When we 'append', assume we're appending to text.  Some MS dhcp servers will
  give us a string with the length including the trailing NUL.  when we 'append
  domain-name', we get something like "search x.y\000 z" in resolv.conf :(
  
  MFC after:	1 week
  Security:	A buffer overflow (by one NUL byte) was possible.

Modified:
  head/sbin/dhclient/dhclient.c

Modified: head/sbin/dhclient/dhclient.c
==============================================================================
--- head/sbin/dhclient/dhclient.c	Mon Jun  8 21:42:15 2009	(r193764)
+++ head/sbin/dhclient/dhclient.c	Mon Jun  8 21:42:30 2009	(r193765)
@@ -1977,7 +1977,7 @@ supersede:
 					len = ip->client->
 					    config->defaults[i].len +
 					    lease->options[i].len;
-					if (len > sizeof(dbuf)) {
+					if (len >= sizeof(dbuf)) {
 						warning("no space to %s %s",
 						    "prepend option",
 						    dhcp_options[i].name);
@@ -1996,24 +1996,34 @@ supersede:
 					dp[len] = '\0';
 					break;
 				case ACTION_APPEND:
+					/*
+					 * When we append, we assume that we're
+					 * appending to text.  Some MS servers
+					 * include a NUL byte at the end of
+					 * the search string provided.
+					 */
 					len = ip->client->
 					    config->defaults[i].len +
 					    lease->options[i].len;
-					if (len > sizeof(dbuf)) {
+					if (len >= sizeof(dbuf)) {
 						warning("no space to %s %s",
 						    "append option",
 						    dhcp_options[i].name);
 						goto supersede;
 					}
-					dp = dbuf;
-					memcpy(dp,
+					memcpy(dbuf,
 						lease->options[i].data,
 						lease->options[i].len);
-					memcpy(dp + lease->options[i].len,
+					for (dp = dbuf + lease->options[i].len;
+					    dp > dbuf; dp--, len--)
+						if (dp[-1] != '\0')
+							break;
+					memcpy(dp,
 						ip->client->
 						config->defaults[i].data,
 						ip->client->
 						config->defaults[i].len);
+					dp = dbuf;
 					dp[len] = '\0';
 				}
 			} else {


More information about the svn-src-all mailing list