Hi,

ber_add_integer() can ASN.1 encode integers of up to 64 bit. Yet for
some types (e.g. SNMP_T_TIMETICKS, SNMP_T_GAUGE32, ..) the MIB says that
the value must no exceed 2^32-1. We should cast the value to u_int32_t
to avoid that e.g. Gauge32 carries a value larger than 32 bit.

One special thing is the interface baud rate, where the MIB in RFC 2863
states that the value should be truncated to 4,294,967,295 in case it is
"greater than the maximum value reportable by this object".


Gerhard


Index: usr.sbin/snmpd/mib.c
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/mib.c,v
retrieving revision 1.80
diff -u -p -u -p -r1.80 mib.c
--- usr.sbin/snmpd/mib.c        17 Nov 2015 12:30:23 -0000      1.80
+++ usr.sbin/snmpd/mib.c        28 Jan 2016 12:19:01 -0000
@@ -155,7 +155,7 @@ mib_getsys(struct oid *oid, struct ber_o
                break;
        case 3:
                ticks = smi_getticks();
-               *elm = ber_add_integer(*elm, ticks);
+               *elm = ber_add_integer(*elm, (u_int32_t)ticks);
                ber_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
                break;
        case 4:
@@ -463,7 +463,8 @@ mib_hrsystemuptime(struct oid *oid, stru
        if (sysctl(mib, 2, &boottime, &len, NULL, 0) == -1)
                return (-1);
 
-       *elm = ber_add_integer(*elm, (now - boottime.tv_sec) * 100);
+       *elm = ber_add_integer(*elm,
+           (u_int32_t)((now - boottime.tv_sec) * 100));
        ber_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
 
        return (0);
@@ -1079,6 +1080,7 @@ mib_iftable(struct oid *oid, struct ber_
        size_t                   len;
        int                      ifq;
        int                      mib[] = { CTL_NET, PF_INET, IPPROTO_IP, 0, 0 };
+       u_int32_t                baudrate;
 
        /* Get and verify the current row index */
        idx = o->bo_id[OIDIDX_ifEntry];
@@ -1115,7 +1117,11 @@ mib_iftable(struct oid *oid, struct ber_
                ber = ber_add_integer(ber, kif->if_mtu);
                break;
        case 5:
-               ber = ber_add_integer(ber, kif->if_baudrate);
+               if (kif->if_baudrate <= UINT32_MAX)
+                       baudrate = kif->if_baudrate;
+               else
+                       baudrate = UINT32_MAX;
+               ber = ber_add_integer(ber, baudrate);
                ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_GAUGE32);
                break;
        case 6:
@@ -1145,7 +1151,7 @@ mib_iftable(struct oid *oid, struct ber_
                ber = ber_add_integer(ber, i);
                break;
        case 9:
-               ber = ber_add_integer(ber, kif->if_ticks);
+               ber = ber_add_integer(ber, (u_int32_t)kif->if_ticks);
                ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
                break;
        case 10:
@@ -1328,7 +1334,7 @@ int
 mib_ifstacklast(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
 {
        struct ber_element      *ber = *elm;
-       ber = ber_add_integer(ber, kr_iflastchange());
+       ber = ber_add_integer(ber, (u_int32_t)kr_iflastchange());
        ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
        return (0);
 }
@@ -1667,7 +1673,7 @@ mib_pfinfo(struct oid *oid, struct ber_o
                else
                        runtime = 0;
                runtime *= 100;
-               *elm = ber_add_integer(*elm, runtime);
+               *elm = ber_add_integer(*elm, (u_int32_t)runtime);
                ber_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
                break;
        case 3:
@@ -2168,7 +2174,7 @@ mib_pftables(struct oid *oid, struct ber
                break;
        case 20:
                tzero = (time(NULL) - ts.pfrts_tzero) * 100;
-               ber = ber_add_integer(ber, tzero);
+               ber = ber_add_integer(ber, (u_int32_t)tzero);
                ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
                break;
        case 21:
@@ -2224,7 +2230,8 @@ mib_pftableaddrs(struct oid *oid, struct
                ber = ber_add_integer(ber, as.pfras_a.pfra_net);
                break;
        case 4:
-               ber = ber_add_integer(ber, (time(NULL) - as.pfras_tzero) * 100);
+               ber = ber_add_integer(ber,
+                   (u_int32_t)((time(NULL) - as.pfras_tzero) * 100));
                ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
                break;
        case 5:
@@ -3044,7 +3051,8 @@ mib_ipstat(struct oid *oid, struct ber_o
        for (i = 0;
            (u_int)i < (sizeof(mapping) / sizeof(mapping[0])); i++) {
                if (oid->o_oid[OIDIDX_ip] == mapping[i].m_id) {
-                       *elm = ber_add_integer(*elm, *mapping[i].m_ptr);
+                       *elm = ber_add_integer(*elm,
+                           (u_int32_t)*mapping[i].m_ptr);
                        ber_set_header(*elm,
                            BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
                        return (0);
@@ -3445,7 +3453,7 @@ static struct oid ipf_mib[] = {
 int
 mib_ipfnroutes(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
 {
-       *elm = ber_add_integer(*elm, kr_routenumber());
+       *elm = ber_add_integer(*elm, (u_int32_t)kr_routenumber());
        ber_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_GAUGE32);
 
        return (0);

Reply via email to