diff --git a/net-snmp-CVE-2014-3565.patch b/net-snmp-CVE-2014-3565.patch new file mode 100644 index 0000000..86af4a0 --- /dev/null +++ b/net-snmp-CVE-2014-3565.patch @@ -0,0 +1,446 @@ +commit 7f4a7b891332899cea26e95be0337aae01648742 +Author: Jan Safranek +Date: Thu Jul 31 13:46:49 2014 +0200 + + Added checks for printing variables with wrong types. + + When -OQ command line argument is used, variable formatter preffers the type + of the varible parsed from a MIB file instead of checking type of the variable + as parsed from SNMP message. + + This can lead to crashes when incoming packets contains a variable with + NULL type, while the MIB says the variable should be non-NULL, like Integer. + The formatter then tries to interpret the NULL (from packet) as Integer (from + MIB file). + +diff --git a/snmplib/mib.c b/snmplib/mib.c +index 9d3ca41..c6e0010 100644 +--- a/snmplib/mib.c ++++ b/snmplib/mib.c +@@ -439,17 +439,16 @@ sprint_realloc_octet_string(u_char ** buf, size_t * buf_len, + u_char *cp; + int output_format, cnt; + +- if ((var->type != ASN_OCTET_STR) && +- (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { +- const char str[] = "Wrong Type (should be OCTET STRING): "; +- if (snmp_cstrcat +- (buf, buf_len, out_len, allow_realloc, str)) { +- return sprint_realloc_by_type(buf, buf_len, out_len, ++ if (var->type != ASN_OCTET_STR) { ++ if (!netsnmp_ds_get_boolean( ++ NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT)) { ++ const char str[] = "Wrong Type (should be OCTET STRING): "; ++ if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, str)) ++ return 0; ++ } ++ return sprint_realloc_by_type(buf, buf_len, out_len, + allow_realloc, var, NULL, NULL, + NULL); +- } else { +- return 0; +- } + } + + +@@ -702,16 +701,16 @@ sprint_realloc_float(u_char ** buf, size_t * buf_len, + const struct enum_list *enums, + const char *hint, const char *units) + { +- if ((var->type != ASN_OPAQUE_FLOAT) && +- (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { +- if (snmp_cstrcat(buf, buf_len, out_len, allow_realloc, +- "Wrong Type (should be Float): ")) { +- return sprint_realloc_by_type(buf, buf_len, out_len, ++ if (var->type != ASN_OPAQUE_FLOAT) { ++ if (!netsnmp_ds_get_boolean( ++ NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT)) { ++ u_char str[] = "Wrong Type (should be Float): "; ++ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) ++ return 0; ++ } ++ return sprint_realloc_by_type(buf, buf_len, out_len, + allow_realloc, var, NULL, NULL, + NULL); +- } else { +- return 0; +- } + } + + if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { +@@ -772,17 +771,16 @@ sprint_realloc_double(u_char ** buf, size_t * buf_len, + const struct enum_list *enums, + const char *hint, const char *units) + { +- if ((var->type != ASN_OPAQUE_DOUBLE) && +- (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { +- if (snmp_cstrcat +- (buf, buf_len, out_len, allow_realloc, +- "Wrong Type (should be Double): ")) { +- return sprint_realloc_by_type(buf, buf_len, out_len, ++ if (var->type != ASN_OPAQUE_DOUBLE) { ++ if (!netsnmp_ds_get_boolean( ++ NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT)) { ++ u_char str[] = "Wrong Type (should be Double): "; ++ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) ++ return 0; ++ } ++ return sprint_realloc_by_type(buf, buf_len, out_len, + allow_realloc, var, NULL, NULL, + NULL); +- } else { +- return 0; +- } + } + + if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { +@@ -847,20 +845,21 @@ sprint_realloc_counter64(u_char ** buf, size_t * buf_len, size_t * out_len, + { + char a64buf[I64CHARSZ + 1]; + +- if ((var->type != ASN_COUNTER64 ++ if (var->type != ASN_COUNTER64 + #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES + && var->type != ASN_OPAQUE_COUNTER64 + && var->type != ASN_OPAQUE_I64 && var->type != ASN_OPAQUE_U64 + #endif +- ) && (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { +- if (snmp_cstrcat(buf, buf_len, out_len, allow_realloc, +- "Wrong Type (should be Counter64): ")) { +- return sprint_realloc_by_type(buf, buf_len, out_len, ++ ) { ++ if (!netsnmp_ds_get_boolean( ++ NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT)) { ++ u_char str[] = "Wrong Type (should be Counter64): "; ++ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) ++ return 0; ++ } ++ return sprint_realloc_by_type(buf, buf_len, out_len, + allow_realloc, var, NULL, NULL, + NULL); +- } else { +- return 0; +- } + } + + if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { +@@ -948,23 +947,25 @@ sprint_realloc_opaque(u_char ** buf, size_t * buf_len, + const struct enum_list *enums, + const char *hint, const char *units) + { +- if ((var->type != ASN_OPAQUE ++ if (var->type != ASN_OPAQUE + #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES + && var->type != ASN_OPAQUE_COUNTER64 + && var->type != ASN_OPAQUE_U64 + && var->type != ASN_OPAQUE_I64 + && var->type != ASN_OPAQUE_FLOAT && var->type != ASN_OPAQUE_DOUBLE + #endif /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */ +- ) && (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { +- if (snmp_cstrcat(buf, buf_len, out_len, allow_realloc, +- "Wrong Type (should be Opaque): ")) { +- return sprint_realloc_by_type(buf, buf_len, out_len, ++ ) { ++ if (!netsnmp_ds_get_boolean( ++ NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT)) { ++ u_char str[] = "Wrong Type (should be Opaque): "; ++ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) ++ return 0; ++ } ++ return sprint_realloc_by_type(buf, buf_len, out_len, + allow_realloc, var, NULL, NULL, + NULL); +- } else { +- return 0; +- } + } ++ + #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES + switch (var->type) { + case ASN_OPAQUE_COUNTER64: +@@ -1040,17 +1041,16 @@ sprint_realloc_object_identifier(u_char ** buf, size_t * buf_len, + { + int buf_overflow = 0; + +- if ((var->type != ASN_OBJECT_ID) && +- (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { +- u_char str[] = +- "Wrong Type (should be OBJECT IDENTIFIER): "; +- if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { +- return sprint_realloc_by_type(buf, buf_len, out_len, ++ if (var->type != ASN_OBJECT_ID) { ++ if (!netsnmp_ds_get_boolean( ++ NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT)) { ++ u_char str[] = "Wrong Type (should be OBJECT IDENTIFIER): "; ++ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) ++ return 0; ++ } ++ return sprint_realloc_by_type(buf, buf_len, out_len, + allow_realloc, var, NULL, NULL, + NULL); +- } else { +- return 0; +- } + } + + if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { +@@ -1110,16 +1110,16 @@ sprint_realloc_timeticks(u_char ** buf, size_t * buf_len, size_t * out_len, + { + char timebuf[40]; + +- if ((var->type != ASN_TIMETICKS) && +- (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { +- u_char str[] = "Wrong Type (should be Timeticks): "; +- if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { +- return sprint_realloc_by_type(buf, buf_len, out_len, ++ if (var->type != ASN_TIMETICKS) { ++ if (!netsnmp_ds_get_boolean( ++ NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT)) { ++ u_char str[] = "Wrong Type (should be Timeticks): "; ++ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) ++ return 0; ++ } ++ return sprint_realloc_by_type(buf, buf_len, out_len, + allow_realloc, var, NULL, NULL, + NULL); +- } else { +- return 0; +- } + } + + if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_NUMERIC_TIMETICKS)) { +@@ -1277,17 +1277,18 @@ sprint_realloc_integer(u_char ** buf, size_t * buf_len, size_t * out_len, + { + char *enum_string = NULL; + +- if ((var->type != ASN_INTEGER) && +- (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { +- u_char str[] = "Wrong Type (should be INTEGER): "; +- if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { +- return sprint_realloc_by_type(buf, buf_len, out_len, ++ if (var->type != ASN_INTEGER) { ++ if (!netsnmp_ds_get_boolean( ++ NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT)) { ++ u_char str[] = "Wrong Type (should be INTEGER): "; ++ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) ++ return 0; ++ } ++ return sprint_realloc_by_type(buf, buf_len, out_len, + allow_realloc, var, NULL, NULL, + NULL); +- } else { +- return 0; +- } + } ++ + for (; enums; enums = enums->next) { + if (enums->value == *var->val.integer) { + enum_string = enums->label; +@@ -1380,16 +1381,16 @@ sprint_realloc_uinteger(u_char ** buf, size_t * buf_len, size_t * out_len, + { + char *enum_string = NULL; + +- if ((var->type != ASN_UINTEGER) && +- (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { +- u_char str[] = "Wrong Type (should be UInteger32): "; +- if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { +- return sprint_realloc_by_type(buf, buf_len, out_len, ++ if (var->type != ASN_UINTEGER) { ++ if (!netsnmp_ds_get_boolean( ++ NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT)) { ++ u_char str[] = "Wrong Type (should be UInteger32): "; ++ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) ++ return 0; ++ } ++ return sprint_realloc_by_type(buf, buf_len, out_len, + allow_realloc, var, NULL, NULL, + NULL); +- } else { +- return 0; +- } + } + + for (; enums; enums = enums->next) { +@@ -1477,17 +1478,16 @@ sprint_realloc_gauge(u_char ** buf, size_t * buf_len, size_t * out_len, + { + char tmp[32]; + +- if ((var->type != ASN_GAUGE) && +- (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { +- u_char str[] = +- "Wrong Type (should be Gauge32 or Unsigned32): "; +- if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { +- return sprint_realloc_by_type(buf, buf_len, out_len, ++ if (var->type != ASN_GAUGE) { ++ if (!netsnmp_ds_get_boolean( ++ NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT)) { ++ u_char str[] = "Wrong Type (should be Gauge32 or Unsigned32): "; ++ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) ++ return 0; ++ } ++ return sprint_realloc_by_type(buf, buf_len, out_len, + allow_realloc, var, NULL, NULL, + NULL); +- } else { +- return 0; +- } + } + + if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { +@@ -1550,16 +1550,16 @@ sprint_realloc_counter(u_char ** buf, size_t * buf_len, size_t * out_len, + { + char tmp[32]; + +- if ((var->type != ASN_COUNTER) && +- (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { +- u_char str[] = "Wrong Type (should be Counter32): "; +- if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { +- return sprint_realloc_by_type(buf, buf_len, out_len, ++ if (var->type != ASN_COUNTER) { ++ if (!netsnmp_ds_get_boolean( ++ NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT)) { ++ u_char str[] = "Wrong Type (should be Counter32): "; ++ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) ++ return 0; ++ } ++ return sprint_realloc_by_type(buf, buf_len, out_len, + allow_realloc, var, NULL, NULL, + NULL); +- } else { +- return 0; +- } + } + + if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { +@@ -1613,16 +1613,16 @@ sprint_realloc_networkaddress(u_char ** buf, size_t * buf_len, + { + size_t i; + +- if ((var->type != ASN_IPADDRESS) && +- (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { +- u_char str[] = "Wrong Type (should be NetworkAddress): "; +- if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { +- return sprint_realloc_by_type(buf, buf_len, out_len, ++ if (var->type != ASN_IPADDRESS) { ++ if (!netsnmp_ds_get_boolean( ++ NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT)) { ++ u_char str[] = "Wrong Type (should be NetworkAddress): "; ++ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) ++ return 0; ++ } ++ return sprint_realloc_by_type(buf, buf_len, out_len, + allow_realloc, var, NULL, NULL, + NULL); +- } else { +- return 0; +- } + } + + if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { +@@ -1679,16 +1679,16 @@ sprint_realloc_ipaddress(u_char ** buf, size_t * buf_len, size_t * out_len, + { + u_char *ip = var->val.string; + +- if ((var->type != ASN_IPADDRESS) && +- (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { +- u_char str[] = "Wrong Type (should be IpAddress): "; +- if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { +- return sprint_realloc_by_type(buf, buf_len, out_len, ++ if (var->type != ASN_IPADDRESS) { ++ if (!netsnmp_ds_get_boolean( ++ NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT)) { ++ u_char str[] = "Wrong Type (should be IpAddress): "; ++ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) ++ return 0; ++ } ++ return sprint_realloc_by_type(buf, buf_len, out_len, + allow_realloc, var, NULL, NULL, + NULL); +- } else { +- return 0; +- } + } + + if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { +@@ -1737,20 +1737,20 @@ sprint_realloc_null(u_char ** buf, size_t * buf_len, size_t * out_len, + const struct enum_list *enums, + const char *hint, const char *units) + { +- if ((var->type != ASN_NULL) && +- (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { +- u_char str[] = "Wrong Type (should be NULL): "; +- if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { +- return sprint_realloc_by_type(buf, buf_len, out_len, ++ if (var->type != ASN_NULL) { ++ if (!netsnmp_ds_get_boolean( ++ NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT)) { ++ u_char str[] = "Wrong Type (should be NULL): "; ++ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) ++ return 0; ++ } ++ return sprint_realloc_by_type(buf, buf_len, out_len, + allow_realloc, var, NULL, NULL, + NULL); +- } else { +- return 0; +- } +- } else { +- u_char str[] = "NULL"; +- return snmp_strcat(buf, buf_len, out_len, allow_realloc, str); + } ++ ++ u_char str[] = "NULL"; ++ return snmp_strcat(buf, buf_len, out_len, allow_realloc, str); + } + + +@@ -1785,16 +1785,16 @@ sprint_realloc_bitstring(u_char ** buf, size_t * buf_len, size_t * out_len, + u_char *cp; + char *enum_string; + +- if ((var->type != ASN_BIT_STR && var->type != ASN_OCTET_STR) && +- (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { +- u_char str[] = "Wrong Type (should be BITS): "; +- if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { +- return sprint_realloc_by_type(buf, buf_len, out_len, ++ if (var->type != ASN_BIT_STR && var->type != ASN_OCTET_STR) { ++ if (!netsnmp_ds_get_boolean( ++ NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT)) { ++ u_char str[] = "Wrong Type (should be BITS): "; ++ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) ++ return 0; ++ } ++ return sprint_realloc_by_type(buf, buf_len, out_len, + allow_realloc, var, NULL, NULL, + NULL); +- } else { +- return 0; +- } + } + + if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { +@@ -1869,16 +1869,16 @@ sprint_realloc_nsapaddress(u_char ** buf, size_t * buf_len, + const struct enum_list *enums, const char *hint, + const char *units) + { +- if ((var->type != ASN_NSAP) && +- (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) { +- u_char str[] = "Wrong Type (should be NsapAddress): "; +- if (snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) { +- return sprint_realloc_by_type(buf, buf_len, out_len, ++ if (var->type != ASN_NSAP) { ++ if (!netsnmp_ds_get_boolean( ++ NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT)) { ++ u_char str[] = "Wrong Type (should be NsapAddress): "; ++ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, str)) ++ return 0; ++ } ++ return sprint_realloc_by_type(buf, buf_len, out_len, + allow_realloc, var, NULL, NULL, + NULL); +- } else { +- return 0; +- } + } + + if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)) { diff --git a/net-snmp.spec b/net-snmp.spec index 9b2492a..ce0f067 100644 --- a/net-snmp.spec +++ b/net-snmp.spec @@ -11,7 +11,7 @@ Summary: A collection of SNMP protocol tools and libraries Name: net-snmp Version: 5.7.2 -Release: 14%{?dist} +Release: 15%{?dist} Epoch: 1 License: BSD @@ -43,6 +43,7 @@ Patch10: net-snmp-5.7.2-btrfs.patch Patch11: net-snmp-5.7-agentx-crash.patch Patch12: net-snmp-5.5-agentx-disconnect-crash.patch Patch13: net-snmp-5.7.2-icmp-mib.patch +Patch14: net-snmp-CVE-2014-3565.patch Requires(post): chkconfig Requires(preun): chkconfig @@ -210,6 +211,7 @@ cp %{SOURCE12} . %patch11 -p1 -b .agentx-crash %patch12 -p1 -b .agentx-disconnect-crash %patch13 -p1 -b .icmp-mib +%patch14 -p1 -b .CVE-2014-3565 %ifarch sparc64 s390 s390x # disable failing test - see https://bugzilla.redhat.com/show_bug.cgi?id=680697 @@ -511,6 +513,9 @@ rm -rf ${RPM_BUILD_ROOT} %{_initrddir}/snmptrapd %changelog +* Mon Sep 1 2014 Jan Safranek - 1:5.7.2-15 +- Fixed CVE-2014-3565 + * Tue Mar 4 2014 Jan Safranek - 1:5.7.2-14 - Fixed buffer overflow in ICMP-MIB (#1071753)