Package: snmpd
Version: 5.1.2-6.1
Severity: normal
Tags: upstream, patch

Hi!

In UCD-SNMP-MIB there are some ssRawCpu* objects defined under
systemStats. I use these for RRD graphics and noticed on one machine
after several months without reboot, that ssRawCpuIdle reached
4294967295 (=2^32-1) and stayed on this instead of rolling over and
starting with 0 again like Counter32 (the type of ssRawCpuIdle) let me
expect.

I searched the code and found the problem in
agent/mibgroup/ucd-snmp/vmstat.c function getstat(), where /proc/stat
is read and the line beginning with "cpu " is read using
sscanf(b, "cpu %lu %lu %lu %lu %lu %lu %lu", cuse, cice, csys,
cide, ciow, cirq, csoft)
This causes trouble if one of the numbers becomes larger than 2^32,
which results in cide been set to 4294967295 instead of dividing it by
2^32 and showing only the rest.

I created the attached patch, which uses sscanf with %llu instead of
%lu and scanning into unsigned long long variables which are casted to
unsigned long at the end, which realizes the 32bit roll over.

My system is Debian sarge with net-snmp 5.1.2-6.1 on i386 Linux 2.6.

For the records here an example of plain 5.1.2-6.1:

$ snmpwalk -v2c -cxxxxx xxx.xxx.xx.xx 1.3.6.1.4.1.2021.11
[...]
UCD-SNMP-MIB::ssCpuRawUser.0 = Counter32: 103338508
UCD-SNMP-MIB::ssCpuRawNice.0 = Counter32: 712456
UCD-SNMP-MIB::ssCpuRawSystem.0 = Counter32: 21972438
UCD-SNMP-MIB::ssCpuRawIdle.0 = Counter32: 4294967295 <---
UCD-SNMP-MIB::ssCpuRawWait.0 = Counter32: 1736944
UCD-SNMP-MIB::ssCpuRawKernel.0 = Counter32: 6566013
UCD-SNMP-MIB::ssCpuRawInterrupt.0 = Counter32: 4044025
[...]

And after applying my patch:

UCD-SNMP-MIB::ssCpuRawUser.0 = Counter32: 103339140
UCD-SNMP-MIB::ssCpuRawNice.0 = Counter32: 712456
UCD-SNMP-MIB::ssCpuRawSystem.0 = Counter32: 21973413
UCD-SNMP-MIB::ssCpuRawIdle.0 = Counter32: 30284027 <---
UCD-SNMP-MIB::ssCpuRawWait.0 = Counter32: 1737308
UCD-SNMP-MIB::ssCpuRawKernel.0 = Counter32: 6566223
UCD-SNMP-MIB::ssCpuRawInterrupt.0 = Counter32: 4044197

I just reported this to the upstream BTS at sorceforge.net as
http://sourceforge.net/tracker/index.php?func=detail&aid=1197183&group_id=12694&atid=112694

Tschoeeee

        Roland

-- System Information:
Debian Release: 3.1
  APT prefers testing
  APT policy: (300, 'testing'), (70, 'unstable'), (1, 'experimental')
Architecture: i386 (i686)
Kernel: Linux 2.4.28
Locale: LANG=de_DE, LC_CTYPE=de_DE (charmap=ISO-8859-1)

Versions of packages snmpd depends on:
ii  libc6                       2.3.2.ds1-21 GNU C Library: Shared libraries an
ii  libsensors3                 1:2.9.1-1    library to read temperature/voltag
ii  libsnmp5                    5.1.2-6.1    NET SNMP (Simple Network Managemen
ii  libwrap0                    7.6.dbs-8    Wietse Venema's TCP wrappers libra

-- no debconf information

-- 
 * [EMAIL PROTECTED] * http://www.spinnaker.de/ *
--- agent/mibgroup/ucd-snmp/vmstat.c.org        2004-04-15 00:32:23.000000000 
+0200
+++ agent/mibgroup/ucd-snmp/vmstat.c    2005-05-07 12:43:52.000000000 +0200
@@ -203,6 +203,8 @@
     static int      bsize = 0, vmbsize = 0;
     char           *b;
     time_t          now;
+    unsigned long long cusell = 0, cicell = 0, csysll = 0, cidell = 0,
+                       ciowll = 0, cirqll = 0, csoftll = 0;
 
     time(&now);
     if (cache_time + CACHE_TIMEOUT < now) {
@@ -245,12 +247,22 @@
     b = strstr(buff, "cpu ");
     if (b) {
        if (!has_cpu_26 ||
-               sscanf(b, "cpu  %lu %lu %lu %lu %lu %lu %lu", cuse, cice, csys,
-                                       cide, ciow, cirq, csoft) != 7) {
+               sscanf(b, "cpu  %llu %llu %llu %llu %llu %llu %llu", &cusell,
+                      &cicell, &csysll, &cidell, &ciowll, &cirqll, &csoftll)
+           != 7) {
            has_cpu_26 = 0;
-           sscanf(b, "cpu  %lu %lu %lu %lu", cuse, cice, csys, cide);
+           sscanf(b, "cpu  %llu %llu %llu %llu", 
+                  &cusell, &cicell, &csysll, &cidell);
            *ciow = *cirq = *csoft = 0;
+       } else {
+           *ciow = (unsigned long)ciowll;
+           *cirq = (unsigned long)cirqll;
+           *csoft = (unsigned long)csoftll;
        }
+       *cuse = (unsigned long)cusell;
+       *cice = (unsigned long)cicell;
+       *csys = (unsigned long)csysll;
+       *cide = (unsigned long)cidell;
     }
     else {
        if (first)

Reply via email to