Date: Sat, 11 Jun 2005 20:30:08 GMT From: Deomid Ryabkov <myself@rojer.pp.ru> To: freebsd-gnats-submit@FreeBSD.org Subject: ports/82148: net-snmp: problem with negative integers on 64-bit platforms Message-ID: <200506112030.j5BKU85s045835@www.freebsd.org> Resent-Message-ID: <200506112030.j5BKUD7u086095@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 82148 >Category: ports >Synopsis: net-snmp: problem with negative integers on 64-bit platforms >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Jun 11 20:30:13 GMT 2005 >Closed-Date: >Last-Modified: >Originator: Deomid Ryabkov >Release: 5.4 >Organization: >Environment: FreeBSD pizza.rbc.ru 5.4-STABLE FreeBSD 5.4-STABLE #0: Fri Jun 10 11:17:47 MSD 2005 rojer@pizza.rbc.ru:/usr/obj/usr/src/sys/RBCSMP64.toxin amd64 >Description: 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. >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%. >Fix: patch-asn1.c, including the fix: --- 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 +#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))) { >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200506112030.j5BKU85s045835>