reading negative integer values (e.g. dskMinPercent) sends snmpd into infinte loop. the problem is specific to platforms with sizeof int > 4 and is not present in original net-snmp, but is introduced by patch-asn1.c. Fix: patch-asn1.c, including the fix: +#if HAVE_UNISTD_H +#include <unistd.h> +#endif #if HAVE_DMALLOC_H #include <dmalloc.h> #endif @@ -584,6 +587,11 @@ return NULL; } integer = *intp; + if (intsize > 4) { + register u_long signmask = ((u_long)1 << ((8 * sizeof(long)) - 1)); + register u_long signbit = ((integer & signmask) != 0); + integer &= (signbit << 31) | 0x7fffffff; + } /* * Truncate "unnecessary" bytes off of the most significant end of this * 2's complement integer. There should be no sequence of 9 @@ -663,6 +671,9 @@ return NULL; } integer = *intp; + if (intsize > 4) { + integer &= 0xffffffff; + } mask = ((u_long) 0xFF) << (8 * (sizeof(long) - 1)); /* * mask is 0xFF000000 on a big-endian machine @@ -2668,19 +2679,26 @@ register long integer = *intp; int testvalue = (*intp < 0) ? -1 : 0; size_t start_offset = *offset; + int imaxbytes = 4; if (intsize != sizeof(long)) { _asn_size_err(errpre, intsize, sizeof(long)); return 0; } + if (intsize > 4) { + register u_long signmask = ((u_long)1 << ((8 * sizeof(long)) - 1)); + register u_long signbit = ((integer & signmask) != 0); + integer &= (signbit << 31) | 0x7fffffff; + } + if (((*pkt_len - *offset) < 1) && !(r && asn_realloc(pkt, pkt_len))) { return 0; } *(*pkt + *pkt_len - (++*offset)) = (u_char) integer; integer >>= 8; - while (integer != testvalue) { + while (integer != testvalue && (--imaxbytes)) { if (((*pkt_len - *offset) < 1) && !(r && asn_realloc(pkt, pkt_len))) { return 0; @@ -2823,6 +2841,10 @@ if (intsize != sizeof(unsigned long)) { _asn_size_err(errpre, intsize, sizeof(unsigned long)); return 0; + } + + if (intsize > 4) { + integer &= 0xffffffff; } if (((*pkt_len - *offset) < 1) && !(r && asn_realloc(pkt, pkt_len))) {--6H2v7S4cHVLvFz2UsJa1pj4qy5ROhFwlJzJwDGrCOP6wHTJp Content-Type: text/plain; name="file.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="file.diff" --- snmplib/asn1.c.orig Fri Dec 10 18:07:16 2004 +++ snmplib/asn1.c Fri Jun 10 20:09:34 2005 @@ -181,6 +181,9 @@ #include <in.h> #endif How-To-Repeat: snmpwalk -v 1 target_host dsk this will output lines up to dskMinimum, getting stuck on dskMinPercent at the same time, snmpd starts to grow in size and the cpu usage is close to 100%.
Responsible Changed From-To: freebsd-ports-bugs->kuriyama Over to maintainer.
Hi, this patch fixes net-snmp on my amd64 Box which used to ate 100% cpu when querying .iso.3.6.1.4.1.2021.4
State Changed From-To: open->closed Patch applied. Thanks!