summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@ozlabs.org>2019-12-31 11:12:07 +1100
committerPaul Mackerras <paulus@ozlabs.org>2019-12-31 12:29:57 +1100
commit5d034034a61c37dc5d590753cb7a601d2ee2b871 (patch)
treea2e2a0364811fdc7f22bc5a0fc3111498debcfd6
parenta1e950a04bcd9b19be22c19aa3bdaa66d9538701 (diff)
downloadppp-5d034034a61c37dc5d590753cb7a601d2ee2b871.tar.gz
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 <paulus@ozlabs.org>
-rw-r--r--pppd/utils.c19
1 files 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 *)"<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)