f000e33bcb
`iconv_sysctl_add` from `sys/libkern/iconv.c` incorrectly limits the size of user strings, such that several out of bounds reads could have been possible. static int iconv_sysctl_add(SYSCTL_HANDLER_ARGS) { struct iconv_converter_class *dcp; struct iconv_cspair *csp; struct iconv_add_in din; struct iconv_add_out dout; int error; error = SYSCTL_IN(req, &din, sizeof(din)); if (error) return error; if (din.ia_version != ICONV_ADD_VER) return EINVAL; if (din.ia_datalen > ICONV_CSMAXDATALEN) return EINVAL; if (strlen(din.ia_from) >= ICONV_CSNMAXLEN) return EINVAL; if (strlen(din.ia_to) >= ICONV_CSNMAXLEN) return EINVAL; if (strlen(din.ia_converter) >= ICONV_CNVNMAXLEN) return EINVAL; ... Since the `din` struct is directly copied from userland, there is no guarantee that the strings supplied will be NULL terminated. The `strlen` calls could continue reading past the designated buffer sizes. Declaration of `struct iconv_add_in` is found in `sys/sys/iconv.h`: struct iconv_add_in { int ia_version; char ia_converter[ICONV_CNVNMAXLEN]; char ia_to[ICONV_CSNMAXLEN]; char ia_from[ICONV_CSNMAXLEN]; int ia_datalen; const void *ia_data; }; Our strings are followed by the `ia_datalen` member, which is checked before the `strlen` calls: if (din.ia_datalen > ICONV_CSMAXDATALEN) Since `ICONV_CSMAXDATALEN` has value `0x41000` (and is `unsigned`), this ensures that `din.ia_datalen` contains at least 1 byte of 0, so it is not possible to trigger a read out of bounds of the `struct` however, this code is fragile and could introduce subtle bugs in the future if the `struct` is ever modified. PR: 207302 Submitted by: CTurt <cturt@hardenedbsd.org> Reported by: CTurt <cturt@hardenedbsd.org> Reviewed by: jhb, vangyzen MFC after: 1 week Sponsored by: Dell EMC Differential Revision: https://reviews.freebsd.org/D14521 |
||
---|---|---|
.. | ||
arm | ||
arm64 | ||
x86 | ||
arc4random.c | ||
ashldi3.c | ||
ashrdi3.c | ||
asprintf.c | ||
bcd.c | ||
bcmp.c | ||
bsearch.c | ||
cmpdi2.c | ||
crc32.c | ||
divdi3.c | ||
explicit_bzero.c | ||
ffs.c | ||
ffsl.c | ||
ffsll.c | ||
fls.c | ||
flsl.c | ||
flsll.c | ||
fnmatch.c | ||
iconv_converter_if.m | ||
iconv_ucs.c | ||
iconv_xlat16.c | ||
iconv_xlat.c | ||
iconv.c | ||
inet_aton.c | ||
inet_ntoa.c | ||
inet_ntop.c | ||
inet_pton.c | ||
jenkins_hash.c | ||
lshrdi3.c | ||
mcount.c | ||
memcchr.c | ||
memchr.c | ||
memcmp.c | ||
memmem.c | ||
memmove.c | ||
memset.c | ||
moddi3.c | ||
murmur3_32.c | ||
qdivrem.c | ||
qsort_r.c | ||
qsort.c | ||
quad.h | ||
random.c | ||
scanc.c | ||
strcasecmp.c | ||
strcat.c | ||
strchr.c | ||
strcmp.c | ||
strcpy.c | ||
strcspn.c | ||
strdup.c | ||
strlcat.c | ||
strlcpy.c | ||
strlen.c | ||
strncat.c | ||
strncmp.c | ||
strncpy.c | ||
strndup.c | ||
strnlen.c | ||
strrchr.c | ||
strsep.c | ||
strspn.c | ||
strstr.c | ||
strtol.c | ||
strtoq.c | ||
strtoul.c | ||
strtouq.c | ||
strvalid.c | ||
timingsafe_bcmp.c | ||
ucmpdi2.c | ||
udivdi3.c | ||
umoddi3.c | ||
zlib.c |