From 5d034034a61c37dc5d590753cb7a601d2ee2b871 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 31 Dec 2019 11:12:07 +1100 Subject: [PATCH] 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 --- pppd/utils.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) 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) -- 2.39.2