Skip site navigation (1)Skip section navigation (2)
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>