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 {