|
1 This patch fixes a security issue where snmp_pdu_parse() function |
|
2 could leave incompletely parsed varBind variables in the list of |
|
3 variables. A remote, unauthenticated attacker could exploit this |
|
4 flaw to cause a crash or, potentially, execute arbitrary code. |
|
5 The vulnerability is fixed in the upsream and below is the link |
|
6 to the upstream bug. |
|
7 https://sourceforge.net/p/net-snmp/bugs/2615/ |
|
8 |
|
9 --- a/snmplib/snmp_api.c Mon Aug 3 03:34:05 2015 |
|
10 +++ b/snmplib/snmp_api.c Mon Aug 3 03:31:01 2015 |
|
11 @@ -4270,10 +4270,9 @@ |
|
12 u_char type; |
|
13 u_char msg_type; |
|
14 u_char *var_val; |
|
15 - int badtype = 0; |
|
16 size_t len; |
|
17 size_t four; |
|
18 - netsnmp_variable_list *vp = NULL; |
|
19 + netsnmp_variable_list *vp = NULL, *vplast = NULL; |
|
20 oid objid[MAX_OID_LEN]; |
|
21 |
|
22 /* |
|
23 @@ -4486,38 +4486,24 @@ |
|
24 (ASN_SEQUENCE | ASN_CONSTRUCTOR), |
|
25 "varbinds"); |
|
26 if (data == NULL) |
|
27 - return -1; |
|
28 + goto fail; |
|
29 |
|
30 /* |
|
31 * get each varBind sequence |
|
32 */ |
|
33 while ((int) *length > 0) { |
|
34 - netsnmp_variable_list *vptemp; |
|
35 - vptemp = (netsnmp_variable_list *) malloc(sizeof(*vptemp)); |
|
36 - if (NULL == vptemp) { |
|
37 - return -1; |
|
38 - } |
|
39 - if (NULL == vp) { |
|
40 - pdu->variables = vptemp; |
|
41 - } else { |
|
42 - vp->next_variable = vptemp; |
|
43 - } |
|
44 - vp = vptemp; |
|
45 - |
|
46 - vp->next_variable = NULL; |
|
47 - vp->val.string = NULL; |
|
48 + vp = SNMP_MALLOC_TYPEDEF(netsnmp_variable_list); |
|
49 + if (NULL == vp) |
|
50 + goto fail; |
|
51 vp->name_length = MAX_OID_LEN; |
|
52 - vp->name = NULL; |
|
53 - vp->index = 0; |
|
54 - vp->data = NULL; |
|
55 - vp->dataFreeHook = NULL; |
|
56 + vp->type = 0; |
|
57 DEBUGDUMPSECTION("recv", "VarBind"); |
|
58 data = snmp_parse_var_op(data, objid, &vp->name_length, &vp->type, |
|
59 &vp->val_len, &var_val, length); |
|
60 if (data == NULL) |
|
61 - return -1; |
|
62 + goto fail; |
|
63 if (snmp_set_var_objid(vp, objid, vp->name_length)) |
|
64 - return -1; |
|
65 + goto fail; |
|
66 |
|
67 len = MAX_PACKET_LENGTH; |
|
68 DEBUGDUMPHEADER("recv", "Value"); |
|
69 @@ -4504,7 +4488,7 @@ |
|
70 vp->val.string = (u_char *) malloc(vp->val_len); |
|
71 } |
|
72 if (vp->val.string == NULL) { |
|
73 - return -1; |
|
74 + goto fail; |
|
75 } |
|
76 asn_parse_string(var_val, &len, &vp->type, vp->val.string, |
|
77 &vp->val_len); |
|
78 @@ -4515,7 +4499,7 @@ |
|
79 vp->val_len *= sizeof(oid); |
|
80 vp->val.objid = (oid *) malloc(vp->val_len); |
|
81 if (vp->val.objid == NULL) { |
|
82 - return -1; |
|
83 + goto fail; |
|
84 } |
|
85 memmove(vp->val.objid, objid, vp->val_len); |
|
86 break; |
|
87 @@ -4527,7 +4511,7 @@ |
|
88 case ASN_BIT_STR: |
|
89 vp->val.bitstring = (u_char *) malloc(vp->val_len); |
|
90 if (vp->val.bitstring == NULL) { |
|
91 - return -1; |
|
92 + goto fail; |
|
93 } |
|
94 asn_parse_bitstring(var_val, &len, &vp->type, |
|
95 vp->val.bitstring, &vp->val_len); |
|
96 @@ -4534,12 +4518,25 @@ |
|
97 break; |
|
98 default: |
|
99 snmp_log(LOG_ERR, "bad type returned (%x)\n", vp->type); |
|
100 - badtype = -1; |
|
101 + goto fail; |
|
102 break; |
|
103 } |
|
104 DEBUGINDENTADD(-4); |
|
105 + if (NULL == vplast) { |
|
106 + pdu->variables = vp; |
|
107 + } else { |
|
108 + vplast->next_variable = vp; |
|
109 + } |
|
110 + vplast = vp; |
|
111 + vp = NULL; |
|
112 } |
|
113 - return badtype; |
|
114 + return 0; |
|
115 + fail: |
|
116 + DEBUGMSGTL(("recv", "error while parsing VarBindList\n")); |
|
117 + /** if we were parsing a var, remove it from the pdu and free it */ |
|
118 + if (vp) |
|
119 + snmp_free_var(vp); |
|
120 + return -1; |
|
121 } |
|
122 |
|
123 /* |