From e69245da77e860cb1f5938212798f2c941b81825 Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Tue, 4 Mar 2014 09:37:08 +0100 Subject: [PATCH] Fixed buffer overflow in ICMP-MIB Resolves #1071753 --- net-snmp-5.7.2-icmp-mib.patch | 146 ++++++++++++++++++++++++++++++++++ net-snmp.spec | 7 +- 2 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 net-snmp-5.7.2-icmp-mib.patch diff --git a/net-snmp-5.7.2-icmp-mib.patch b/net-snmp-5.7.2-icmp-mib.patch new file mode 100644 index 0000000..81cd55a --- /dev/null +++ b/net-snmp-5.7.2-icmp-mib.patch @@ -0,0 +1,146 @@ +1071753 - net-snmp: denial of service flaw in Linux implementation of ICMP-MIB + +commit 8407b6ce46ca7159b3c816d1024e20a53f9a1c6c +Author: Wes Hardaker +Date: Wed Feb 19 15:21:57 2014 -0800 + + bug fix from fenner: fix ICMP mib table handling on linux + +diff --git a/agent/mibgroup/mibII/icmp.c b/agent/mibgroup/mibII/icmp.c +index 14c73a6..6d10426 100644 +--- a/agent/mibgroup/mibII/icmp.c ++++ b/agent/mibgroup/mibII/icmp.c +@@ -106,10 +106,20 @@ struct icmp_msg_stats_table_entry { + int flags; + }; + ++#ifdef linux ++/* Linux keeps track of all possible message types */ ++#define ICMP_MSG_STATS_IPV4_COUNT 256 ++#else + #define ICMP_MSG_STATS_IPV4_COUNT 11 ++#endif + + #ifdef NETSNMP_ENABLE_IPV6 ++#ifdef linux ++/* Linux keeps track of all possible message types */ ++#define ICMP_MSG_STATS_IPV6_COUNT 256 ++#else + #define ICMP_MSG_STATS_IPV6_COUNT 14 ++#endif + #else + #define ICMP_MSG_STATS_IPV6_COUNT 0 + #endif /* NETSNMP_ENABLE_IPV6 */ +@@ -177,7 +187,7 @@ icmp_msg_stats_load(netsnmp_cache *cache, void *vmagic) + inc = 0; + linux_read_icmp_msg_stat(&v4icmp, &v4icmpmsg, &flag); + if (flag) { +- while (254 != k) { ++ while (255 >= k) { + if (v4icmpmsg.vals[k].InType) { + icmp_msg_stats_table[i].ipVer = 1; + icmp_msg_stats_table[i].icmpMsgStatsType = k; +@@ -267,7 +277,7 @@ icmp_msg_stats_load(netsnmp_cache *cache, void *vmagic) + inc = 0; + linux_read_icmp6_msg_stat(&v6icmp, &v6icmpmsg, &flag); + if (flag) { +- while (254 != k) { ++ while (255 >= k) { + if (v6icmpmsg.vals[k].InType) { + icmp_msg_stats_table[i].ipVer = 2; + icmp_msg_stats_table[i].icmpMsgStatsType = k; +@@ -1050,6 +1060,12 @@ icmp_stats_table_handler(netsnmp_mib_handler *handler, + continue; + table_info = netsnmp_extract_table_info(request); + subid = table_info->colnum; ++ DEBUGMSGTL(( "mibII/icmpStatsTable", "oid: " )); ++ DEBUGMSGOID(( "mibII/icmpStatsTable", request->requestvb->name, ++ request->requestvb->name_length )); ++ DEBUGMSG(( "mibII/icmpStatsTable", " In %d InErr %d Out %d OutErr %d\n", ++ entry->icmpStatsInMsgs, entry->icmpStatsInErrors, ++ entry->icmpStatsOutMsgs, entry->icmpStatsOutErrors )); + + switch (subid) { + case ICMP_STAT_INMSG: +@@ -1117,6 +1133,11 @@ icmp_msg_stats_table_handler(netsnmp_mib_handler *handler, + continue; + table_info = netsnmp_extract_table_info(request); + subid = table_info->colnum; ++ DEBUGMSGTL(( "mibII/icmpMsgStatsTable", "oid: " )); ++ DEBUGMSGOID(( "mibII/icmpMsgStatsTable", request->requestvb->name, ++ request->requestvb->name_length )); ++ DEBUGMSG(( "mibII/icmpMsgStatsTable", " In %d Out %d Flags 0x%x\n", ++ entry->icmpMsgStatsInPkts, entry->icmpMsgStatsOutPkts, entry->flags )); + + switch (subid) { + case ICMP_MSG_STAT_IN_PKTS: +diff --git a/agent/mibgroup/mibII/kernel_linux.c b/agent/mibgroup/mibII/kernel_linux.c +index b21a166..ba320c7 100644 +--- a/agent/mibgroup/mibII/kernel_linux.c ++++ b/agent/mibgroup/mibII/kernel_linux.c +@@ -81,9 +81,9 @@ decode_icmp_msg(char *line, char *data, struct icmp4_msg_mib *msg) + index = strtol(token, &delim, 0); + if (ERANGE == errno) { + continue; +- } else if (index > LONG_MAX) { ++ } else if (index > 255) { + continue; +- } else if (index < LONG_MIN) { ++ } else if (index < 0) { + continue; + } + if (NULL == (token = strtok_r(dataptr, " ", &saveptr1))) +@@ -94,9 +94,9 @@ decode_icmp_msg(char *line, char *data, struct icmp4_msg_mib *msg) + index = strtol(token, &delim, 0); + if (ERANGE == errno) { + continue; +- } else if (index > LONG_MAX) { ++ } else if (index > 255) { + continue; +- } else if (index < LONG_MIN) { ++ } else if (index < 0) { + continue; + } + if(NULL == (token = strtok_r(dataptr, " ", &saveptr1))) +@@ -426,14 +426,21 @@ linux_read_icmp6_parse(struct icmp6_mib *icmp6stat, + + vals = name; + if (NULL != icmp6msgstat) { ++ int type; + if (0 == strncmp(name, "Icmp6OutType", 12)) { + strsep(&vals, "e"); +- icmp6msgstat->vals[atoi(vals)].OutType = stats; ++ type = atoi(vals); ++ if ( type < 0 || type > 255 ) ++ continue; ++ icmp6msgstat->vals[type].OutType = stats; + *support = 1; + continue; + } else if (0 == strncmp(name, "Icmp6InType", 11)) { + strsep(&vals, "e"); +- icmp6msgstat->vals[atoi(vals)].InType = stats; ++ type = atoi(vals); ++ if ( type < 0 || type > 255 ) ++ continue; ++ icmp6msgstat->vals[type].InType = stats; + *support = 1; + continue; + } +diff --git a/agent/mibgroup/mibII/kernel_linux.h b/agent/mibgroup/mibII/kernel_linux.h +index 6bf5d47..c6dfca9 100644 +--- a/agent/mibgroup/mibII/kernel_linux.h ++++ b/agent/mibgroup/mibII/kernel_linux.h +@@ -121,11 +121,11 @@ struct icmp_msg_mib { + + /* Lets use wrapper structures for future expansion */ + struct icmp4_msg_mib { +- struct icmp_msg_mib vals[255]; ++ struct icmp_msg_mib vals[256]; + }; + + struct icmp6_msg_mib { +- struct icmp_msg_mib vals[255]; ++ struct icmp_msg_mib vals[256]; + }; + + struct udp_mib { diff --git a/net-snmp.spec b/net-snmp.spec index 59bef63..9b2492a 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: 13%{?dist} +Release: 14%{?dist} Epoch: 1 License: BSD @@ -42,6 +42,7 @@ Patch9: net-snmp-5.7.2-autoreconf.patch 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 Requires(post): chkconfig Requires(preun): chkconfig @@ -208,6 +209,7 @@ cp %{SOURCE12} . %patch10 -p1 -b .btrfs %patch11 -p1 -b .agentx-crash %patch12 -p1 -b .agentx-disconnect-crash +%patch13 -p1 -b .icmp-mib %ifarch sparc64 s390 s390x # disable failing test - see https://bugzilla.redhat.com/show_bug.cgi?id=680697 @@ -509,6 +511,9 @@ rm -rf ${RPM_BUILD_ROOT} %{_initrddir}/snmptrapd %changelog +* Tue Mar 4 2014 Jan Safranek - 1:5.7.2-14 +- Fixed buffer overflow in ICMP-MIB (#1071753) + * Thu Dec 5 2013 Jan Safranek - 1:5.7.2-13 - Fixed snmpd crashing when AgentX subagent disconnects in the middle of request processing (#1038011)