Print this page
5378 CVE-2014-3158 ppp: integer overflow in option parsing
Reviewed by: Robert Mustacchi <rm@joyent.com>


  14  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT.  SUN SHALL NOT BE LIABLE FOR
  15  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  16  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES
  17  *
  18  * Copyright (c) 1989 Carnegie Mellon University.
  19  * All rights reserved.
  20  *
  21  * Redistribution and use in source and binary forms are permitted
  22  * provided that the above copyright notice and this paragraph are
  23  * duplicated in all such forms and that any documentation,
  24  * advertising materials, and other materials related to such
  25  * distribution and use acknowledge that the software was developed
  26  * by Carnegie Mellon University.  The name of the
  27  * University may not be used to endorse or promote products derived
  28  * from this software without specific prior written permission.
  29  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  30  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  31  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  32  */
  33 
  34 #pragma ident   "%Z%%M% %I%     %E% SMI"
  35 #define RCSID   "$Id: options.c,v 1.74 2000/04/15 01:27:13 masputra Exp $"
  36 
  37 #include <ctype.h>
  38 #include <stdio.h>
  39 #include <errno.h>
  40 #include <unistd.h>
  41 #include <fcntl.h>
  42 #include <stdlib.h>
  43 #include <syslog.h>
  44 #include <string.h>
  45 #include <netdb.h>
  46 #include <pwd.h>
  47 #include <sys/types.h>
  48 #include <sys/stat.h>
  49 #include <netinet/in.h>
  50 #include <arpa/inet.h>
  51 #ifdef PLUGIN
  52 #include <dlfcn.h>
  53 #endif /* PLUGIN */
  54 #ifdef PPP_FILTER


1298                         digit = (islower(c) ? toupper(c) : c) - '0';
1299                         if (digit > 10 || digit < 0)      /* allow non-ASCII */
1300                             digit += '0' + 10 - 'A';
1301                         value = (value << 4) + digit;
1302                         c = getc (f);
1303                     }
1304                     got = 1;
1305                     break;
1306                 }
1307 
1308                 /*
1309                  * Otherwise the character stands for itself.
1310                  */
1311                 value = c;
1312                 break;
1313             }
1314 
1315             /*
1316              * Store the resulting character for the escape sequence.
1317              */
1318             if (len < MAXWORDLEN-1)
1319                 word[len] = value;
1320             ++len;

1321 
1322             if (!got)
1323                 c = getc(f);
1324             continue;
1325 
1326         }
1327 
1328         /*
1329          * Not escaped: see if we've reached the end of the word.
1330          */
1331         if (quoted) {
1332             if (c == quoted)
1333                 break;
1334         } else {
1335             if (isspace(c) || c == '#') {
1336                 (void) ungetc (c, f);
1337                 break;
1338             }
1339         }
1340 
1341         /*
1342          * Backslash starts an escape sequence.
1343          */
1344         if (c == '\\') {
1345             escape = 1;
1346             c = getc(f);
1347             continue;
1348         }
1349 
1350         /*
1351          * An ordinary character: store it in the word and get another.
1352          */
1353         if (len < MAXWORDLEN-1)
1354             word[len] = c;
1355         ++len;

1356 
1357         c = getc(f);
1358     }
1359 
1360     /*
1361      * End of the word: check for errors.
1362      */
1363     if (c == EOF) {
1364         if (ferror(f)) {
1365             if (errno == 0)
1366                 errno = EIO;
1367             option_error("Error reading %s: %m", filename);
1368             die(1);
1369         }
1370         /*
1371          * If len is zero, then we didn't find a word before the
1372          * end of the file.
1373          */
1374         if (len == 0)
1375             return (0);




  14  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT.  SUN SHALL NOT BE LIABLE FOR
  15  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  16  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES
  17  *
  18  * Copyright (c) 1989 Carnegie Mellon University.
  19  * All rights reserved.
  20  *
  21  * Redistribution and use in source and binary forms are permitted
  22  * provided that the above copyright notice and this paragraph are
  23  * duplicated in all such forms and that any documentation,
  24  * advertising materials, and other materials related to such
  25  * distribution and use acknowledge that the software was developed
  26  * by Carnegie Mellon University.  The name of the
  27  * University may not be used to endorse or promote products derived
  28  * from this software without specific prior written permission.
  29  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  30  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  31  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  32  */
  33 

  34 #define RCSID   "$Id: options.c,v 1.74 2000/04/15 01:27:13 masputra Exp $"
  35 
  36 #include <ctype.h>
  37 #include <stdio.h>
  38 #include <errno.h>
  39 #include <unistd.h>
  40 #include <fcntl.h>
  41 #include <stdlib.h>
  42 #include <syslog.h>
  43 #include <string.h>
  44 #include <netdb.h>
  45 #include <pwd.h>
  46 #include <sys/types.h>
  47 #include <sys/stat.h>
  48 #include <netinet/in.h>
  49 #include <arpa/inet.h>
  50 #ifdef PLUGIN
  51 #include <dlfcn.h>
  52 #endif /* PLUGIN */
  53 #ifdef PPP_FILTER


1297                         digit = (islower(c) ? toupper(c) : c) - '0';
1298                         if (digit > 10 || digit < 0)      /* allow non-ASCII */
1299                             digit += '0' + 10 - 'A';
1300                         value = (value << 4) + digit;
1301                         c = getc (f);
1302                     }
1303                     got = 1;
1304                     break;
1305                 }
1306 
1307                 /*
1308                  * Otherwise the character stands for itself.
1309                  */
1310                 value = c;
1311                 break;
1312             }
1313 
1314             /*
1315              * Store the resulting character for the escape sequence.
1316              */
1317             if (len < MAXWORDLEN) {
1318                 word[len] = value;
1319                 ++len;
1320             }
1321 
1322             if (!got)
1323                 c = getc(f);
1324             continue;
1325 
1326         }
1327 
1328         /*
1329          * Not escaped: see if we've reached the end of the word.
1330          */
1331         if (quoted) {
1332             if (c == quoted)
1333                 break;
1334         } else {
1335             if (isspace(c) || c == '#') {
1336                 (void) ungetc (c, f);
1337                 break;
1338             }
1339         }
1340 
1341         /*
1342          * Backslash starts an escape sequence.
1343          */
1344         if (c == '\\') {
1345             escape = 1;
1346             c = getc(f);
1347             continue;
1348         }
1349 
1350         /*
1351          * An ordinary character: store it in the word and get another.
1352          */
1353         if (len < MAXWORDLEN) {
1354             word[len] = c;
1355             ++len;
1356         }
1357 
1358         c = getc(f);
1359     }
1360 
1361     /*
1362      * End of the word: check for errors.
1363      */
1364     if (c == EOF) {
1365         if (ferror(f)) {
1366             if (errno == 0)
1367                 errno = EIO;
1368             option_error("Error reading %s: %m", filename);
1369             die(1);
1370         }
1371         /*
1372          * If len is zero, then we didn't find a word before the
1373          * end of the file.
1374          */
1375         if (len == 0)
1376             return (0);