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:
parent
70e47040b0
commit
61ab25cd3d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=286169
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user