libctf: Fix an out-of-bounds read in ctf_lookup_by_name()

When prefixes such as struct, union, etc. are compared with the current
type (e.g. struct foo), a comparison is made with the prefix.  The code
currently assumes that every type is a valid C type with a prefix,
however at times, garbage ends up in this function causing an
unpredictable crash with DTrace due to the isspace(*p) call or
subsequent calls. An example that I've seen of this is the letter 's'
being passed in, comparing true with struct as the comparison size was
(q - p) == 1, but then we increment p with the length of "struct",
resulting in an out of bounds read.

Reviewed by:	markj
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D29435
This commit is contained in:
Domagoj Stolfa 2021-03-27 14:04:12 -04:00 committed by Mark Johnston
parent 71c160a8f6
commit 410556f1f1

View File

@ -132,8 +132,9 @@ ctf_lookup_by_name(ctf_file_t *fp, const char *name)
continue; /* skip qualifier keyword */
for (lp = fp->ctf_lookups; lp->ctl_prefix != NULL; lp++) {
if (lp->ctl_prefix[0] == '\0' ||
strncmp(p, lp->ctl_prefix, (size_t)(q - p)) == 0) {
if ((size_t)(q - p) >= lp->ctl_len &&
(lp->ctl_prefix[0] == '\0' ||
strncmp(p, lp->ctl_prefix, (size_t)(q - p)) == 0)) {
for (p += lp->ctl_len; isspace(*p); p++)
continue; /* skip prefix and next ws */