mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-30 08:19:09 +00:00
iconv uses strlen directly on user supplied memory
`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
This commit is contained in:
parent
fae9c380ce
commit
2b08b42bae
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=330027
@ -413,11 +413,11 @@ iconv_sysctl_add(SYSCTL_HANDLER_ARGS)
|
||||
return EINVAL;
|
||||
if (din.ia_datalen > ICONV_CSMAXDATALEN)
|
||||
return EINVAL;
|
||||
if (strlen(din.ia_from) >= ICONV_CSNMAXLEN)
|
||||
if (strnlen(din.ia_from, sizeof(din.ia_from)) >= ICONV_CSNMAXLEN)
|
||||
return EINVAL;
|
||||
if (strlen(din.ia_to) >= ICONV_CSNMAXLEN)
|
||||
if (strnlen(din.ia_to, sizeof(din.ia_to)) >= ICONV_CSNMAXLEN)
|
||||
return EINVAL;
|
||||
if (strlen(din.ia_converter) >= ICONV_CNVNMAXLEN)
|
||||
if (strnlen(din.ia_converter, sizeof(din.ia_converter)) >= ICONV_CNVNMAXLEN)
|
||||
return EINVAL;
|
||||
if (iconv_lookupconv(din.ia_converter, &dcp) != 0)
|
||||
return EINVAL;
|
||||
|
Loading…
Reference in New Issue
Block a user