From 61ab25cd3d89c5169a3a56ce13a30bb92ffef8d9 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Sun, 2 Aug 2015 00:18:48 +0000 Subject: Perform bounds checking when constructing a format string. This was detected by the FORTIFY_SOURCE build. PR: 201657 Reported by: pfg MFC after: 2 weeks --- .../opensolaris/lib/libdtrace/common/dt_printf.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'cddl/contrib') diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c index ae26d55ba8be..d408aed45199 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c @@ -1348,6 +1348,7 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv, dtrace_aggdesc_t *agg; caddr_t lim = (caddr_t)buf + len, limit; char format[64] = "%"; + size_t ret; int i, aggrec, curagg = -1; uint64_t normal; @@ -1379,7 +1380,9 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv, int prec = pfd->pfd_prec; int rval; + const char *start; char *f = format + 1; /* skip initial '%' */ + size_t fmtsz = sizeof(format) - 1; const dtrace_recdesc_t *rec; dt_pfprint_f *func; caddr_t addr; @@ -1536,6 +1539,7 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv, break; } + start = f; if (pfd->pfd_flags & DT_PFCONV_ALT) *f++ = '#'; if (pfd->pfd_flags & DT_PFCONV_ZPAD) @@ -1548,6 +1552,7 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv, *f++ = '\''; if (pfd->pfd_flags & DT_PFCONV_SPACE) *f++ = ' '; + fmtsz -= f - start; /* * If we're printing a stack and DT_PFCONV_LEFT is set, we @@ -1558,13 +1563,20 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv, if (func == pfprint_stack && (pfd->pfd_flags & DT_PFCONV_LEFT)) width = 0; - if (width != 0) - f += snprintf(f, sizeof (format), "%d", ABS(width)); + if (width != 0) { + ret = snprintf(f, fmtsz, "%d", ABS(width)); + f += ret; + fmtsz = MAX(0, fmtsz - ret); + } - if (prec > 0) - f += snprintf(f, sizeof (format), ".%d", prec); + if (prec > 0) { + ret = snprintf(f, fmtsz, ".%d", prec); + f += ret; + fmtsz = MAX(0, fmtsz - ret); + } - (void) strcpy(f, pfd->pfd_fmt); + if (strlcpy(f, pfd->pfd_fmt, fmtsz) >= fmtsz) + return (dt_set_errno(dtp, EDT_COMPILER)); pfd->pfd_rec = rec; if (func(dtp, fp, format, pfd, addr, size, normal) < 0) -- cgit v1.2.3