]> git.ozlabs.org Git - ppp.git/commitdiff
pppd: Avoid use of strnlen (and strlen) in vslprintf
authorPaul Mackerras <paulus@ozlabs.org>
Tue, 31 Dec 2019 00:12:07 +0000 (11:12 +1100)
committerPaul Mackerras <paulus@ozlabs.org>
Tue, 31 Dec 2019 01:29:57 +0000 (12:29 +1100)
Commit b311e98b ("pppd: Limit memory accessed by string formats with
max length specified") added calls to strnlen() in vslprintf().
Unfortunately, strnlen() is not provided in some standard C libraries.
This changes the code to avoid using strnlen().  Using the observation
that the number of characters we can use from the input string is
bounded by buflen, the number of bytes of output buffer available,
we can also avoid doing strlen() on a potentially long string.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
pppd/utils.c

index 2cc0e9110f9383105e9b9c85333a269c1cb20d44..3602aa61674ab23c538d6e3cebdea511cde42a6e 100644 (file)
@@ -166,6 +166,7 @@ vslprintf(buf, buflen, fmt, args)
     u_int32_t ip;
     static char hexchars[] = "0123456789abcdef";
     struct buffer_info bufinfo;
+    int termch;
 
     buf0 = buf;
     --buflen;
@@ -299,14 +300,17 @@ vslprintf(buf, buflen, fmt, args)
                    p = (unsigned char *)"<NULL>";
            if (fillch == '0' && prec >= 0) {
                n = prec;
+               termch = -1;    /* matches no unsigned char value */
            } else {
-               if (prec == -1)
-                   n = strlen((char *)p);
-               else
-                   n = strnlen((char *)p, prec);
+               n = buflen;
+               if (prec != -1 && n > prec)
+                   n = prec;
+               termch = 0;     /* stop on null byte */
            }
            while (n > 0 && buflen > 0) {
                c = *p++;
+               if (c == termch)
+                   break;
                --n;
                if (!quoted && c >= 0x80) {
                    OUTCHAR('M');
@@ -386,10 +390,9 @@ vslprintf(buf, buflen, fmt, args)
            }
            len = num + sizeof(num) - 1 - str;
        } else {
-           if (prec == -1)
-               len = strlen(str);
-           else
-               len = strnlen(str, prec);
+           for (len = 0; len < buflen && (prec == -1 || len < prec); ++len)
+               if (str[len] == 0)
+                   break;
        }
        if (width > 0) {
            if (width > buflen)