Gerhard Roth
2016-01-28 12:40:51 UTC
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);
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);