Bug 82148 - net-snmp: problem with negative integers on 64-bit platforms
Summary: net-snmp: problem with negative integers on 64-bit platforms
Status: Closed FIXED
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: Normal Affects Only Me
Assignee: Jun Kuriyama
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-06-11 21:30 UTC by Deomid Ryabkov
Modified: 2005-07-13 03:39 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Deomid Ryabkov 2005-06-11 21:30:13 UTC
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%.
Comment 1 Mark Linimon freebsd_committer freebsd_triage 2005-06-12 02:15:33 UTC
Responsible Changed
From-To: freebsd-ports-bugs->kuriyama

Over to maintainer.
Comment 2 Oliver Lehmann freebsd_committer freebsd_triage 2005-06-12 02:49:21 UTC
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
Comment 3 Jun Kuriyama freebsd_committer freebsd_triage 2005-07-13 03:39:18 UTC
State Changed
From-To: open->closed

Patch applied.  Thanks!