SOURCES: net-snmp-64bit-error-checking.patch (NEW) - new; [ 125996...

zawadaa zawadaa at pld-linux.org
Sun Feb 18 11:46:57 CET 2007


Author: zawadaa                      Date: Sun Feb 18 10:46:57 2007 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- new; [ 1259966 ] 5.2.1 32 bit overflow issues

---- Files affected:
SOURCES:
   net-snmp-64bit-error-checking.patch (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/net-snmp-64bit-error-checking.patch
diff -u /dev/null SOURCES/net-snmp-64bit-error-checking.patch:1.1
--- /dev/null	Sun Feb 18 11:46:57 2007
+++ SOURCES/net-snmp-64bit-error-checking.patch	Sun Feb 18 11:46:52 2007
@@ -0,0 +1,544 @@
+diff -ruN net-snmp-5.2.1.2.orig/snmplib/asn1.c net-snmp-5.2.1.2/snmplib/asn1.c
+--- net-snmp-5.2.1.2.orig/snmplib/asn1.c	2004-12-10 15:07:16.000000000 +0000
++++ net-snmp-5.2.1.2/snmplib/asn1.c	2007-02-17 23:54:03.000000000 +0000
+@@ -470,6 +470,13 @@
+     while (asn_length--)
+         value = (value << 8) | *bufp++;
+ 
++#if SIZEOF_LONG != 4
++    if ((unsigned long)value > 0xffffffff) {
++        snmp_log(LOG_ERR,"truncating integer value to 32 bits\n");
++        value &= 0xffffffff;
++    }
++#endif
++
+     DEBUGMSG(("dumpv_recv", "  Integer:\t%ld (0x%.2X)\n", value, value));
+ 
+     *intp = value;
+@@ -535,6 +542,13 @@
+     while (asn_length--)
+         value = (value << 8) | *bufp++;
+ 
++#if SIZEOF_LONG != 4
++    if (value > 0xffffffff) {
++        snmp_log(LOG_ERR,"truncating uinteger value to 32 bits\n");
++        value &= 0xffffffff;
++    }
++#endif
++
+     DEBUGMSG(("dumpv_recv", "  UInteger:\t%ld (0x%.2X)\n", value, value));
+ 
+     *intp = value;
+@@ -584,6 +598,12 @@
+         return NULL;
+     }
+     integer = *intp;
++#if SIZEOF_LONG != 4
++    if ((unsigned long)integer > 0xffffffff) {
++        snmp_log(LOG_ERR,"truncating integer value to 32 bits\n");
++        integer &= 0xffffffff;
++    }
++#endif
+     /*
+      * Truncate "unnecessary" bytes off of the most significant end of this
+      * 2's complement integer.  There should be no sequence of 9
+@@ -663,6 +683,12 @@
+         return NULL;
+     }
+     integer = *intp;
++#if SIZEOF_LONG != 4
++    if (integer > 0xffffffff) {
++        snmp_log(LOG_ERR,"truncating uinteger value to 32 bits\n");
++        integer &= 0xffffffff;
++    }
++#endif
+     mask = ((u_long) 0xFF) << (8 * (sizeof(long) - 1));
+     /*
+      * mask is 0xFF000000 on a big-endian machine 
+@@ -1286,18 +1312,13 @@
+                 (subidentifier << 7) + (*(u_char *) bufp & ~ASN_BIT8);
+             length--;
+         } while (*(u_char *) bufp++ & ASN_BIT8);        /* last byte has high bit clear */
+-        /*
+-         * ?? note, this test will never be true, since the largest value
+-         * of subidentifier is the value of MAX_SUBID! 
+-         *
+-         * Yes: PC-LINT says the same thing
+-         * No!: the agent can be configured to use a char instead of a long
+-         *      for OIDs, in which case this test is essential.
+-         */
++
++#if defined(EIGHTBIT_SUBIDS) || (SIZEOF_LONG != 4)
+         if (subidentifier > (u_long) MAX_SUBID) {
+             ERROR_MSG("subidentifier too large");
+             return NULL;
+         }
++#endif
+         *oidp++ = (oid) subidentifier;
+     }
+ 
+@@ -1439,6 +1460,12 @@
+         if (i >= (int) objidlength)
+             break;
+         objid_val = *op++;	/* XXX - doesn't handle 2.X (X > 40) */
++#if SIZEOF_LONG != 4
++        if (objid_val > 0xffffffff) {
++            snmp_log(LOG_ERR,"truncating objid value to 32 bits\n");
++            objid_val &= 0xffffffff;
++        }
++#endif
+     }
+ 
+     /*
+@@ -1454,8 +1481,13 @@
+      */
+     for (i = 1, objid_val = first_objid_val, op = objid + 2;
+          i < (int) objidlength; i++) {
+-        if (i != 1)
++        if (i != 1) {
+             objid_val = *op++;
++#if SIZEOF_LONG != 4
++            if (objid_val > 0xffffffff) /* already logged warning above */
++                objid_val &= 0xffffffff;
++#endif
++        }
+         switch (objid_size[i]) {
+         case 1:
+             *data++ = (u_char) objid_val;
+@@ -1783,6 +1815,17 @@
+         low = (low << 8) | *bufp++;
+     }
+ 
++#if SIZEOF_LONG != 4
++    if (high > 0xffffffff) {
++        snmp_log(LOG_ERR,"truncating counter64 high value to 32 bits\n");
++        high &= 0xffffffff;
++    }
++    if (low > 0xffffffff) {
++        snmp_log(LOG_ERR,"truncating counter64 low value to 32 bits\n");
++        low &= 0xffffffff;
++    }
++#endif
++
+     cp->low = low;
+     cp->high = high;
+ 
+@@ -1843,6 +1886,16 @@
+     intsize = 8;
+     low = cp->low;
+     high = cp->high;
++#if SIZEOF_LONG != 4
++    if (high > 0xffffffff) {
++        snmp_log(LOG_ERR,"truncating counter64 high value to 32 bits\n");
++        high &= 0xffffffff;
++    }
++    if (low > 0xffffffff) {
++        snmp_log(LOG_ERR,"truncating counter64 low value to 32 bits\n");
++        low &= 0xffffffff;
++    }
++#endif
+     mask = ((u_long) 0xFF) << (8 * (sizeof(long) - 1));
+     /*
+      * mask is 0xFF000000 on a big-endian machine 
+@@ -2041,6 +2094,17 @@
+         low = (low << 8) | *bufp++;
+     }
+ 
++#if SIZEOF_LONG != 4
++    if (high > 0xffffffff) {
++        snmp_log(LOG_ERR,"truncating counter64 high value to 32 bits\n");
++        high &= 0xffffffff;
++    }
++    if (low > 0xffffffff) {
++        snmp_log(LOG_ERR,"truncating counter64 low value to 32 bits\n");
++        low &= 0xffffffff;
++    }
++#endif
++
+     cp->low = low;
+     cp->high = high;
+ 
+@@ -2103,6 +2167,16 @@
+     memcpy(&c64, cp, sizeof(struct counter64)); /* we're may modify it */
+     low = c64.low;
+     high = c64.high;
++#if SIZEOF_LONG != 4
++    if (high > 0xffffffff) {
++        snmp_log(LOG_ERR,"truncating counter64 high value to 32 bits\n");
++        high &= 0xffffffff;
++    }
++    if (low > 0xffffffff) {
++        snmp_log(LOG_ERR,"truncating counter64 low value to 32 bits\n");
++        low &= 0xffffffff;
++    }
++#endif
+ 
+     /*
+      * Truncate "unnecessary" bytes off of the most significant end of this
+@@ -2673,6 +2747,12 @@
+         _asn_size_err(errpre, intsize, sizeof(long));
+         return 0;
+     }
++#if SIZEOF_LONG != 4
++    if ((unsigned long)integer > 0xffffffff) {
++        snmp_log(LOG_ERR,"truncating integer value to 32 bits\n");
++        integer &= 0xffffffff;
++    }
++#endif
+ 
+     if (((*pkt_len - *offset) < 1) && !(r && asn_realloc(pkt, pkt_len))) {
+         return 0;
+@@ -2825,6 +2905,13 @@
+         return 0;
+     }
+ 
++#if SIZEOF_LONG != 4
++    if (integer > 0xffffffff) {
++        snmp_log(LOG_ERR,"truncating uinteger value to 32 bits\n");
++        integer &= 0xffffffff;
++    }
++#endif
++
+     if (((*pkt_len - *offset) < 1) && !(r && asn_realloc(pkt, pkt_len))) {
+         return 0;
+     }
+@@ -2960,6 +3047,12 @@
+     } else {
+         for (i = objidlength; i > 2; i--) {
+             tmpint = objid[i - 1];
++#if SIZEOF_LONG != 4
++            if ((unsigned long)tmpint > 0xffffffff) {
++                snmp_log(LOG_ERR,"truncating oid subid to 32 bits\n");
++                tmpint &= 0xffffffff;
++            }
++#endif
+ 
+             if (((*pkt_len - *offset) < 1)
+                 && !(r && asn_realloc(pkt, pkt_len))) {
+@@ -3176,6 +3269,16 @@
+                       sizeof(struct counter64));
+         return 0;
+     }
++#if SIZEOF_LONG != 4
++    if (high > 0xffffffff) {
++        snmp_log(LOG_ERR,"truncating counter64 high value to 32 bits\n");
++        high &= 0xffffffff;
++    }
++    if (low > 0xffffffff) {
++        snmp_log(LOG_ERR,"truncating counter64 low value to 32 bits\n");
++        low &= 0xffffffff;
++    }
++#endif
+ 
+     /*
+      * Encode the low 4 bytes first.  
+@@ -3359,6 +3462,17 @@
+         return 0;
+     }
+ 
++#if SIZEOF_LONG != 4
++    if (high > 0xffffffff) {
++        snmp_log(LOG_ERR,"truncating counter64 high value to 32 bits\n");
++        high &= 0xffffffff;
++    }
++    if (low > 0xffffffff) {
++        snmp_log(LOG_ERR,"truncating counter64 low value to 32 bits\n");
++        low &= 0xffffffff;
++    }
++#endif
++
+     /*
+      * Encode the low 4 bytes first.  
+      */
+diff -ruN net-snmp-5.2.1.2.orig/snmplib/int64.c net-snmp-5.2.1.2/snmplib/int64.c
+--- net-snmp-5.2.1.2.orig/snmplib/int64.c	2004-07-11 04:28:45.000000000 +0000
++++ net-snmp-5.2.1.2/snmplib/int64.c	2007-02-17 23:54:03.000000000 +0000
+@@ -179,7 +179,9 @@
+      */
+     pu64->low = (ulT1 + u16) & 0x0FFFFFFFFL;
+     pu64->high++;
+-
++#if SIZEOF_LONG != 4
++    pu64->high &= 0xffffffff;
++#endif
+ }                               /* incrByV16 */
+ 
+ void
+@@ -188,8 +190,15 @@
+     unsigned int    tmp;
+     tmp = pu64->low;
+     pu64->low += u32;
+-    if (pu64->low < tmp)
++#if SIZEOF_LONG != 4
++    pu64->low &= 0xffffffff;
++#endif
++    if (pu64->low < tmp) {
+         pu64->high++;
++#if SIZEOF_LONG != 4
++        pu64->high &= 0xffffffff;
++#endif
++    }
+ }
+ 
+ /**
+@@ -214,6 +223,9 @@
+ u64Incr(U64 * pu64out, const U64 * pu64one)
+ {
+     pu64out->high += pu64one->high;
++#if SIZEOF_LONG != 4
++    pu64out->high &= 0xffffffff;
++#endif
+     incrByU32(pu64out, pu64one->low);
+ }
+ 
+@@ -247,7 +259,6 @@
+ void
+ zeroU64(U64 * pu64)
+ {
+-
+     pu64->low = 0;
+     pu64->high = 0;
+ }                               /* zeroU64 */
+@@ -315,8 +326,12 @@
+      */
+     if (new_val->high == old_val->high) {
+         DEBUGMSGTL(("c64:check_wrap", "32 bit wrap\n"));
+-        if (adjust)
++        if (adjust) {
+             ++new_val->high;
++#if SIZEOF_LONG != 4
++            new_val->high &= 0xffffffff;
++#endif
++        }
+         return 32;
+     }
+     else if ((new_val->high == (old_val->high + 1)) ||
+diff -ruN net-snmp-5.2.1.2.orig/snmplib/snmp_client.c net-snmp-5.2.1.2/snmplib/snmp_client.c
+--- net-snmp-5.2.1.2.orig/snmplib/snmp_client.c	2004-12-10 02:21:38.000000000 +0000
++++ net-snmp-5.2.1.2/snmplib/snmp_client.c	2007-02-17 23:54:43.000000000 +0000
+@@ -94,6 +94,7 @@
+ 
+ #include <net-snmp/library/snmp_api.h>
+ #include <net-snmp/library/snmp_client.h>
++#include <net-snmp/library/snmp_logging.h>
+ #include <net-snmp/library/snmp_secmod.h>
+ #include <net-snmp/library/mib.h>
+ 
+@@ -714,41 +715,193 @@
+  */
+ 
+ int
+-snmp_set_var_value(netsnmp_variable_list * newvar,
+-                   const u_char * val_str, size_t val_len)
++snmp_set_var_value(netsnmp_variable_list * vars,
++                   const u_char * value, size_t len)
+ {
++    int             largeval = 1;
++
+     /*
+      * xxx-rks: why the unconditional free? why not use existing
+-     * memory, if val_len < newvar->val_len ?
++     * memory, if len < vars->val_len ?
+      */
+-    if (newvar->val.string && newvar->val.string != newvar->buf) {
+-        free(newvar->val.string);
++    if (vars->val.string && vars->val.string != vars->buf) {
++        free(vars->val.string);
+     }
+-
+-    newvar->val.string = 0;
+-    newvar->val_len = 0;
++    vars->val.string = 0;
++    vars->val_len = 0;
+ 
+     /*
+-     * need a pointer and a length to copy a string value. 
++     * use built-in storage for smaller values 
+      */
+-    if (val_str && val_len) {
+-        if (val_len <= sizeof(newvar->buf))
+-            newvar->val.string = newvar->buf;
+-        else {
+-            newvar->val.string = (u_char *) malloc(val_len);
+-            if (!newvar->val.string)
+-                return 1;
+-        }
+-        memmove(newvar->val.string, val_str, val_len);
+-        newvar->val_len = val_len;
+-    } else if (val_str) {
++    if (len <= (sizeof(vars->buf) - 1)) {
++        vars->val.string = (u_char *) vars->buf;
++        largeval = 0;
++    }
++
++    if ((0 == len) || (NULL == value)) {
++        vars->val.string[0] = 0;
++        return 0;
++    }
++
++    vars->val_len = len;
++    switch (vars->type) {
++    case ASN_INTEGER:
++    case ASN_UNSIGNED:
++    case ASN_TIMETICKS:
++    case ASN_IPADDRESS:
++    case ASN_COUNTER:
++        if (value) {
++            if (vars->val_len == sizeof(int)) {
++                if (ASN_INTEGER == vars->type) {
++                    const int      *val_int 
++                        = (const int *) value;
++                    *(vars->val.integer) = (long) *val_int;
++                } else {
++                    const u_int    *val_uint
++                        = (const u_int *) value;
++                    *(vars->val.integer) = (unsigned long) *val_uint;
++                }
++            }
++#if SIZEOF_LONG != SIZEOF_INT
++            else if (vars->val_len == sizeof(long)){
++                const u_long   *val_ulong
++                    = (const u_long *) value;
++                *(vars->val.integer) = *val_ulong;
++                if (*(vars->val.integer) > 0xffffffff) {
++                    snmp_log(LOG_ERR,"truncating integer value > 32 bits\n");
++                    *(vars->val.integer) &= 0xffffffff;
++                }
++            }
++#endif
++#if SIZEOF_LONG != SIZEOF_LONG_LONG
++            else if (vars->val_len == sizeof(long long)){
++                const unsigned long long   *val_ullong
++                    = (const unsigned long long *) value;
++                *(vars->val.integer) = (long) *val_ullong;
++                if (*(vars->val.integer) > 0xffffffff) {
++                    snmp_log(LOG_ERR,"truncating integer value > 32 bits\n");
++                    *(vars->val.integer) &= 0xffffffff;
++                }
++            }
++#endif
++#if SIZEOF_SHORT != SIZEOF_INT
++            else if (vars->val_len == sizeof(short)) {
++                if (ASN_INTEGER == vars->type) {
++                    const short      *val_short 
++                        = (const short *) value;
++                    *(vars->val.integer) = (long) *val_short;
++                } else {
++                    const u_short    *val_ushort
++                        = (const u_short *) value;
++                    *(vars->val.integer) = (unsigned long) *val_ushort;
++                }
++            }
++#endif
++            else if (vars->val_len == sizeof(char)) {
++                if (ASN_INTEGER == vars->type) {
++                    const char      *val_char 
++                        = (const char *) value;
++                    *(vars->val.integer) = (long) *val_char;
++                } else {
++                    *(vars->val.integer) = (unsigned long) *value;
++                }
++            }
++            else {
++                snmp_log(LOG_ERR,"bad size for integer-like type (%d)\n",
++                         vars->val_len);
++                return (1);
++            }
++        } else
++            *(vars->val.integer) = 0;
++        vars->val_len = sizeof(long);
++        break;
++
++    case ASN_OBJECT_ID:
++    case ASN_PRIV_IMPLIED_OBJECT_ID:
++    case ASN_PRIV_INCL_RANGE:
++    case ASN_PRIV_EXCL_RANGE:
++        if (largeval) {
++            vars->val.objid = (oid *) malloc(vars->val_len);
++        }
++        if (vars->val.objid == NULL) {
++            snmp_log(LOG_ERR,"no storage for OID\n");
++            return 1;
++        }
++        memmove(vars->val.objid, value, vars->val_len);
++        break;
++
++    case ASN_PRIV_IMPLIED_OCTET_STR:
++    case ASN_OCTET_STR:
++    case ASN_BIT_STR:
++    case ASN_OPAQUE:
++    case ASN_NSAP:
++        if (largeval) {
++            vars->val.string = (u_char *) malloc(vars->val_len + 1);
++        }
++        if (vars->val.string == NULL) {
++            snmp_log(LOG_ERR,"no storage for OID\n");
++            return 1;
++        }
++        memmove(vars->val.string, value, vars->val_len);
+         /*
+-         * NULL STRING != NULL ptr 
++         * Make sure the string is zero-terminated; some bits of code make
++         * this assumption.  Easier to do this here than fix all these wrong
++         * assumptions.  
+          */
+-        newvar->val.string = newvar->buf;
+-        newvar->val.string[0] = '\0';
+-        newvar->val_len = 0;
++        vars->val.string[vars->val_len] = '\0';
++        break;
++
++    case SNMP_NOSUCHOBJECT:
++    case SNMP_NOSUCHINSTANCE:
++    case SNMP_ENDOFMIBVIEW:
++    case ASN_NULL:
++        vars->val_len = 0;
++        vars->val.string = NULL;
++        break;
++
++#ifdef OPAQUE_SPECIAL_TYPES
++    case ASN_OPAQUE_U64:
++    case ASN_OPAQUE_I64:
++#endif                          /* OPAQUE_SPECIAL_TYPES */
++    case ASN_COUNTER64:
++        if (largeval) {
++            snmp_log(LOG_ERR,"bad size for counter 64 (%d)\n",
++                     vars->val_len);
++            return (1);
++        }
++        vars->val_len = sizeof(struct counter64);
++        memmove(vars->val.counter64, value, vars->val_len);
++        break;
++
++#ifdef OPAQUE_SPECIAL_TYPES
++    case ASN_OPAQUE_FLOAT:
++        if (largeval) {
++            snmp_log(LOG_ERR,"bad size for opaque float (%d)\n",
++                     vars->val_len);
++            return (1);
++        }
++        vars->val_len = sizeof(float);
++        memmove(vars->val.floatVal, value, vars->val_len);
++        break;
++
++    case ASN_OPAQUE_DOUBLE:
++        if (largeval) {
++            snmp_log(LOG_ERR,"bad size for opaque double (%d)\n",
++                     vars->val_len);
++            return (1);
++        }
++        vars->val_len = sizeof(double);
++        memmove(vars->val.doubleVal, value, vars->val_len);
++        break;
++
++#endif                          /* OPAQUE_SPECIAL_TYPES */
++
++    default:
++        snmp_log(LOG_ERR,"no storage for OID\n");
++        snmp_set_detail("Internal error in type switching\n");
++        return (1);
+     }
++
+     return 0;
+ }
+ 
================================================================


More information about the pld-cvs-commit mailing list