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
This commit is contained in:
Mark Johnston 2015-08-02 00:18:48 +00:00
parent 70e47040b0
commit 61ab25cd3d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=286169

View File

@ -1348,6 +1348,7 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv,
dtrace_aggdesc_t *agg; dtrace_aggdesc_t *agg;
caddr_t lim = (caddr_t)buf + len, limit; caddr_t lim = (caddr_t)buf + len, limit;
char format[64] = "%"; char format[64] = "%";
size_t ret;
int i, aggrec, curagg = -1; int i, aggrec, curagg = -1;
uint64_t normal; 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 prec = pfd->pfd_prec;
int rval; int rval;
const char *start;
char *f = format + 1; /* skip initial '%' */ char *f = format + 1; /* skip initial '%' */
size_t fmtsz = sizeof(format) - 1;
const dtrace_recdesc_t *rec; const dtrace_recdesc_t *rec;
dt_pfprint_f *func; dt_pfprint_f *func;
caddr_t addr; caddr_t addr;
@ -1536,6 +1539,7 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv,
break; break;
} }
start = f;
if (pfd->pfd_flags & DT_PFCONV_ALT) if (pfd->pfd_flags & DT_PFCONV_ALT)
*f++ = '#'; *f++ = '#';
if (pfd->pfd_flags & DT_PFCONV_ZPAD) 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++ = '\''; *f++ = '\'';
if (pfd->pfd_flags & DT_PFCONV_SPACE) if (pfd->pfd_flags & DT_PFCONV_SPACE)
*f++ = ' '; *f++ = ' ';
fmtsz -= f - start;
/* /*
* If we're printing a stack and DT_PFCONV_LEFT is set, we * 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)) if (func == pfprint_stack && (pfd->pfd_flags & DT_PFCONV_LEFT))
width = 0; width = 0;
if (width != 0) if (width != 0) {
f += snprintf(f, sizeof (format), "%d", ABS(width)); ret = snprintf(f, fmtsz, "%d", ABS(width));
f += ret;
fmtsz = MAX(0, fmtsz - ret);
}
if (prec > 0) if (prec > 0) {
f += snprintf(f, sizeof (format), ".%d", prec); 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; pfd->pfd_rec = rec;
if (func(dtp, fp, format, pfd, addr, size, normal) < 0) if (func(dtp, fp, format, pfd, addr, size, normal) < 0)