xorl %eax, %eax

CVE-2012-2141: net-snmp Read out-of-bounds

leave a comment »

This issue was reported by Jan Lieskovsky and we can find the susceptible code in agent/mibgroup/agent/extend.c file. Here is the exact function as seen in 5.6.1.1 version of Net-SNMP package.

/*
 *  Multi-line output handler
 *  Locate the appropriate entry (using _extend_find_entry)
 *  and return the appropriate output line
 */
int
handle_nsExtendOutput2Table(netsnmp_mib_handler          *handler,
                     netsnmp_handler_registration *reginfo,
                     netsnmp_agent_request_info   *reqinfo,
                     netsnmp_request_info         *requests)
{
    netsnmp_request_info       *request;
    netsnmp_table_request_info *table_info;
    netsnmp_extend             *extension;
    char *cp;
    int line_idx;
    int len;

    for ( request=requests; request; request=request->next ) {
        if (request->processed)
            continue;

        table_info = netsnmp_extract_table_info( request );
        extension  = _extend_find_entry( request, table_info, reqinfo->mode );
 ...
        if (!extension) {
 ...
        }

        switch (reqinfo->mode) {
        case MODE_GET:
        case MODE_GETNEXT:
            switch (table_info->colnum) {
            case COLUMN_EXTOUT2_OUTLINE:
                /* 
                 * Determine which line we've been asked for....
                 */
                line_idx = *table_info->indexes->next_variable->val.integer;
                cp  = extension->lines[line_idx-1];

                /* 
                 * ... and how long it is.
                 */
                if ( extension->numlines > line_idx )
                    len = (extension->lines[line_idx])-cp -1;
                else if (cp)
                    len = strlen(cp);
                else
                    len = 0;

                snmp_set_var_typed_value( request->requestvb,
                                          ASN_OCTET_STR, cp, len );
                break;
            default:
                netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
                continue;
            }
            break;
        default:
            netsnmp_set_request_error(reqinfo, request, SNMP_ERR_GENERR);
            return SNMP_ERR_GENERR;
        }
    }
    return SNMP_ERR_NOERROR;
}

From the code comments we can easily find out what this function is used for. Next, from the above routine we can see a signed integer named ‘line_idx’ which is used as an index to the extension table. Consequently, if a user requests (via SNMP GET or GETNEXT) an entry from a certain MIB sub-tree that is beyond the extension table’s bounds it will lead to read out-of-bounds since there are no bounds checks. If this does not crash the application it will result in an invalid pointer stored in ‘cp’ variable.
To fix this bug, the following patch was applied.

                  * Determine which line we've been asked for....
                  */
                 line_idx = *table_info->indexes->next_variable->val.integer;
+                if (line_idx < 1 || line_idx > extension->numlines) {
+                    netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
+                    continue;
+                }
                 cp  = extension->lines[line_idx-1];

This checks that the index value is not less than one and not more than the actual lines of the extension table.

Written by xorl

May 11, 2012 at 23:56

Posted in bugs

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s