Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Feb 2016 10:32:36 +0000
From:      bugzilla-noreply@freebsd.org
To:        freebsd-bugs@FreeBSD.org
Subject:   [Bug 207302] Iconv uses strlen directly on user supplied memory
Message-ID:  <bug-207302-8@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D207302

            Bug ID: 207302
           Summary: Iconv uses strlen directly on user supplied memory
           Product: Base System
           Version: 11.0-CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: kern
          Assignee: freebsd-bugs@FreeBSD.org
          Reporter: cturt@hardenedbsd.org

`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 possibl=
e.

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 =3D SYSCTL_IN(req, &din, sizeof(din));
        if (error)
                return error;
        if (din.ia_version !=3D ICONV_ADD_VER)
                return EINVAL;
        if (din.ia_datalen > ICONV_CSMAXDATALEN)
                return EINVAL;
        if (strlen(din.ia_from) >=3D ICONV_CSNMAXLEN)
                return EINVAL;
        if (strlen(din.ia_to) >=3D ICONV_CSNMAXLEN)
                return EINVAL;
        if (strlen(din.ia_converter) >=3D ICONV_CNVNMAXLEN)
                return EINVAL;
...

Since the `din` struct is directly copied from userland, there is no guaran=
tee
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 ev=
er
modified.

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-207302-8>