xorl %eax, %eax

CVE-2009-1887: NetSNMP RHEL Remote Divide by Zero

leave a comment »

This issue was reported by Tomas Hoger on 19 June 2009 and it affects net-snmp 5.0.9 release in Red Hat Enterprise Linux 3. The vulnerable code is available at agent/snmp_agent.c as you can see below.

/*
 * snmp_agent.c
 *
 * Simple Network Management Protocol (RFC 1067).
 */
      ...
int
netsnmp_create_subtree_cache(netsnmp_agent_session *asp)
{
      ...
    int             i = 0, n = 0, r = 0;
      ...
    if (asp->pdu->command == SNMP_MSG_GETBULK) {
        /*
         * getbulk prep 
         */
        int             count = count_varbinds(asp->pdu->variables);
      ...
        if (asp->pdu->errstat < count) {
            n = asp->pdu->errstat;
        } else {
            n = count;
        }
        if ((r = count - n) < 0) {
            r = 0;
            asp->bulkcache = NULL;
        } else {
      ...
            int maxresponses =
                netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
                                   NETSNMP_DS_AGENT_MAX_GETBULKRESPONSES);

            if (maxresponses == 0)
                maxresponses = 100;   /* more than reasonable default */
      ...
            /* ensure that the maximum number of repetitions will fit in the
             * result vector
             */
            if (maxbulk <= 0 || maxbulk > maxresponses / r)
                maxbulk = maxresponses / r;
      ...
    return SNMPERR_SUCCESS;
}

It checks if the session’s command is set to SNMP_MSG_GETBULK, this command is used when requesting large amount of data and it requires two variables, non-repeaters field that represents the number of variables that should not be iterated and max-repetitions which is the maximum number of iterations. In the above code, you can see that maxresponces is a user controlled integer derived using netsnmp_ds_get_int(), it is immediately checked for not being zero and during the last shown if statement it attempts to divide this by r. From the given code you can easily deduce that r can be zero and consequently result in a floating point exception because of division by zero during the execution of: maxresponses / r.
As Tomas Hoger noted, this issue doesn’t affect upstream net-snmp versions because they had patched it since February 2004 like that:

@@ -358,6 +358,10 @@
     if ((r = asp->vbcount - n) < 0) {
         r = 0;
     }
+
+    /* we do nothing if there is nothing repeated */
+    if (r == 0)
+        return;
             
     /*
      * For each of the original repeating varbinds (except the last),
@@ -1951,7 +1955,7 @@
         } else {
             n = count;
         }
-        if ((r = count - n) < 0) {
+        if ((r = count - n) <= 0) {
             r = 0;
             asp->bulkcache = NULL;
         } else {

And this way, r cannot be zero.

Written by xorl

July 3, 2009 at 12:05

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