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 {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to