From: Paul Mackerras Date: Tue, 31 Dec 2019 00:12:07 +0000 (+1100) Subject: pppd: Avoid use of strnlen (and strlen) in vslprintf X-Git-Tag: ppp-2.4.8~1 X-Git-Url: https://git.ozlabs.org/?a=commitdiff_plain;h=5d034034a61c37dc5d590753cb7a601d2ee2b871;hp=a1e950a04bcd9b19be22c19aa3bdaa66d9538701;p=ppp.git pppd: Avoid use of strnlen (and strlen) in vslprintf 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 --- diff --git a/pppd/utils.c b/pppd/utils.c index 2cc0e91..3602aa6 100644 --- a/pppd/utils.c +++ b/pppd/utils.c @@ -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 *)""; 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)