[Midnightbsd-cvs] src: usr.sbin/ppp: Correct a buffer overflow in ppp command prompt

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Mon Mar 10 21:44:45 EDT 2008


Log Message:
-----------
Correct a buffer overflow in ppp command prompt parsing reported on bugtraq.

Obtained from OpenBSD.

Modified Files:
--------------
    src/usr.sbin/ppp:
        command.c (r1.1.1.1 -> r1.2)
        systems.c (r1.1.1.1 -> r1.2)
        systems.h (r1.1.1.1 -> r1.2)

-------------- next part --------------
Index: systems.h
===================================================================
RCS file: /home/cvs/src/usr.sbin/ppp/systems.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L usr.sbin/ppp/systems.h -L usr.sbin/ppp/systems.h -u -r1.1.1.1 -r1.2
--- usr.sbin/ppp/systems.h
+++ usr.sbin/ppp/systems.h
@@ -40,4 +40,4 @@
 extern void CloseSecret(FILE *);
 extern int AllowUsers(struct cmdargs const *);
 extern int AllowModes(struct cmdargs const *);
-extern const char *InterpretArg(const char *, char *);
+extern const char *InterpretArg(const char *, char *, size_t);
Index: systems.c
===================================================================
RCS file: /home/cvs/src/usr.sbin/ppp/systems.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L usr.sbin/ppp/systems.c -L usr.sbin/ppp/systems.c -u -r1.1.1.1 -r1.2
--- usr.sbin/ppp/systems.c
+++ usr.sbin/ppp/systems.c
@@ -66,7 +66,7 @@
 
 /* Move string from ``from'' to ``to'', interpreting ``~'' and $.... */
 const char *
-InterpretArg(const char *from, char *to)
+InterpretArg(const char *from, char *to, size_t tosiz)
 {
   char *ptr, *startto, *endto;
   struct passwd *pwd;
@@ -76,12 +76,14 @@
 
   instring = 0;
   startto = to;
-  endto = to + LINE_LEN - 1;
+  endto = to + tosiz - 1;
 
   while(issep(*from))
     from++;
 
   while (*from != '\0') {
+    if (to >= endto)
+      return NULL;
     switch (*from) {
       case '"':
         instring = !instring;
@@ -97,6 +99,8 @@
             *to++ = '\\';	/* Pass the escapes on, maybe skipping \# */
             break;
         }
+        if (to >= endto)
+          return NULL;
         *to++ = *from++;
         break;
       case '$':
@@ -127,9 +131,13 @@
             *ptr++ = *from;
           *ptr = '\0';
         }
+        if (to >= endto)
+          return NULL;
         if (*to == '\0')
           *to++ = '$';
         else if ((env = getenv(to)) != NULL) {
+          if ((size_t) (endto - to) < strlen(env))
+            return NULL;
           strncpy(to, env, endto - to);
           *endto = '\0';
           to += strlen(to);
@@ -142,19 +150,24 @@
         if (len == 0)
           pwd = getpwuid(ID0realuid());
         else {
+          if ((size_t) (endto - to) < len)
+            return NULL;
           strncpy(to, from, len);
           to[len] = '\0';
           pwd = getpwnam(to);
         }
+        if (to >= endto)
+          return NULL;
         if (pwd == NULL)
           *to++ = '~';
         else {
+          if ((size_t) (endto - to) < strlen(pwd->pw_dir))
+            return NULL;
           strncpy(to, pwd->pw_dir, endto - to);
           *endto = '\0';
           to += strlen(to);
           from += len;
         }
-        endpwent();
         break;
 
       default:
@@ -179,12 +192,16 @@
 #define CTRL_INCLUDE (1)
 
 static int
-DecodeCtrlCommand(char *line, char *arg)
+DecodeCtrlCommand(char *line, char *arg, size_t argsiz)
 {
   const char *end;
 
   if (!strncasecmp(line, "include", 7) && issep(line[7])) {
-    end = InterpretArg(line+8, arg);
+  end = InterpretArg(line+8, arg, argsiz);
+    if (end == NULL) {
+      log_Printf(LogWARN, "Failed to expand command '%s': too long for the destination buffer\n", line);
+      return CTRL_UNKNOWN;
+    }
     if (*end && *end != '#')
       log_Printf(LogWARN, "usage: !include filename\n");
     else
@@ -353,7 +370,7 @@
       break;
 
     case '!':
-      switch (DecodeCtrlCommand(cp+1, arg)) {
+      switch (DecodeCtrlCommand(cp+1, arg, LINE_LEN)) {
       case CTRL_INCLUDE:
         log_Printf(LogCOMMAND, "%s: Including \"%s\"\n", filename, arg);
         n = ReadSystem(bundle, name, arg, prompt, cx, how);
Index: command.c
===================================================================
RCS file: /home/cvs/src/usr.sbin/ppp/command.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L usr.sbin/ppp/command.c -L usr.sbin/ppp/command.c -u -r1.1.1.1 -r1.2
--- usr.sbin/ppp/command.c
+++ usr.sbin/ppp/command.c
@@ -1132,7 +1132,10 @@
 {
   char buff2[LINE_LEN-offset];
 
-  InterpretArg(buff, buff2);
+  if (InterpretArg(buff, buff2, sizeof buff2) == NULL) {
+    log_Printf(LogWARN, "Failed to expand command '%s': too long for the destination buffer\n", buff);
+    return -1;
+  }
   strncpy(buff, buff2, LINE_LEN - offset - 1);
   buff[LINE_LEN - offset - 1] = '\0';
 


More information about the Midnightbsd-cvs mailing list