[UNIX] Sbus PROM Driver Multiple Integer Overflows

From: SecuriTeam (support_at_securiteam.com)
Date: 07/04/04

  • Next message: SecuriTeam: "[TOOL] netUstad, Network Managament Tool"
    To: list@securiteam.com
    Date: 4 Jul 2004 19:09:59 +0200
    
    

    The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
    - - promotion

    The SecuriTeam alerts list - Free, Accurate, Independent.

    Get your security news from a reliable source.
    http://www.securiteam.com/mailinglist.html

    - - - - - - - - -

      Sbus PROM Driver Multiple Integer Overflows
    ------------------------------------------------------------------------

    SUMMARY

    Sbus PROM is a character device driver allows user programs to access the
    PROM device tree. It is compatible with the SunOS /dev/openprom driver and
    the NetBSD /dev/openprom driver. The SunOS eeprom utility works without
    any modifications. A vulnerability in the device driver allows a local
    attacker to cause a DOS, and possibly code execution depending on location
    of the overflowed buffer in the slab.

    DETAILS

    There exist multiple integer overflows in routines that handle copying in
    user supplied data. In both routines, user supplied parameters are used to
    allocate buffers after being added to another number. Passing certain
    values will result in integer overflows and small buffers being allocated.
    Then large amounts of user data are copied into these buffers. Both of the
    functions in which the overflows occur are 'utility' functions called from
    multiple other functions. An ioctl() call is the simplest way to access
    them.

    Technical Detail:
    The copyin() and the copyin_string() function are both vulnerable:

    /* Copy in a whole string from userspace into kernelspace. */
    static int copyin_string(char *user, size_t len, char **ptr)
    {
            char *tmp;

        /* ME: it's not signed; if( len + 1 < len ) .. */
    1] if (len < 0 || len + 1 < 0)
                    return -EINVAL;

    2] tmp = kmalloc(len + 1, GFP_KERNEL);
            if (!tmp)
                    return -ENOMEM;

    3] if(copy_from_user(tmp, user, len)) {
                    kfree(tmp);
                    return -EFAULT;
            }
    .... snip .....

    In this function it appears they forgot that size_t is not signed. The
    checks made at 1] will never be true, and by passing in ~0 for the len
    variable an integer overflow occurs at 2]. Then at 3] user supplied data
    is copied int this buffer. In various ioctl() calls for both the BSD and
    Sun versions the user has full control over the user and len variables.
     
    static int copyin(struct openpromio *info, struct openpromio **opp_p)
    {
            int bufsize;

            if (!info || !opp_p)
                    return -EFAULT;

    1] if (get_user(bufsize, &info->oprom_size))
                    return -EFAULT;

            if (bufsize == 0)
                    return -EINVAL;

            /* If the bufsize is too large, just limit it.
             * Fix from Jason Rappleye.
             * ME: apparently not fixed enough
             */
    2] if (bufsize > OPROMMAXPARAM)
                    bufsize = OPROMMAXPARAM;

    3] if (!(*opp_p = kmalloc(sizeof(int) + bufsize + 1, GFP_KERNEL)))
                    return -ENOMEM;
            memset(*opp_p, 0, sizeof(int) + bufsize + 1);

    4] if (copy_from_user(&(*opp_p)->oprom_array,
                               &info->oprom_array, bufsize)) {
                    kfree(*opp_p);
                    return -EFAULT;
            }
            return bufsize;
    }

    The bufsize integer variable obtained from the user at 1] is checked for
    being too large at 2], but it is not checked for being negative. We then
    have an overflow occurring at 3] when the buffer is allocated. Then at 4]
    this buffer is used to hold user data, resulting in memory being
    overwritten.

    Vendor Status:
    The driver authors from the source listing were contacted and didn't
    reply.

    ADDITIONAL INFORMATION

    The information has been provided by <mailto:infamous41md@hotpop.com>
    infamous41md.

    ========================================

    This bulletin is sent to members of the SecuriTeam mailing list.
    To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
    In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

    ====================
    ====================

    DISCLAIMER:
    The information in this bulletin is provided "AS IS" without warranty of any kind.
    In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.


  • Next message: SecuriTeam: "[TOOL] netUstad, Network Managament Tool"

    Relevant Pages