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