Skip to content

Commit 748bce1

Browse files
authored
Fix walk memory ownership (#21)
1 parent 428794e commit 748bce1

1 file changed

Lines changed: 41 additions & 13 deletions

File tree

‎netsnmp/client_intf.c‎

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1919,7 +1919,7 @@ netsnmp_walk(PyObject *self, PyObject *args)
19191919
netsnmp_session *ss;
19201920
netsnmp_pdu *pdu, *response;
19211921
netsnmp_pdu *newpdu;
1922-
netsnmp_variable_list *vars, *oldvars;
1922+
netsnmp_variable_list *vars;
19231923
struct tree *tp;
19241924
int len;
19251925
oid **oid_arr = NULL;
@@ -1984,6 +1984,11 @@ netsnmp_walk(PyObject *self, PyObject *args)
19841984

19851985
pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
19861986

1987+
if (!pdu) {
1988+
PyErr_NoMemory();
1989+
goto done;
1990+
}
1991+
19871992
/* we need an initial count for memory allocation */
19881993
varlist_iter = PyObject_GetIter(varlist);
19891994
varlist_len = 0;
@@ -1998,11 +2003,24 @@ netsnmp_walk(PyObject *self, PyObject *args)
19982003
oid_arr = calloc(varlist_len, sizeof(oid *));
19992004
oid_arr_broken_check = calloc(varlist_len, sizeof(oid *));
20002005

2006+
if (varlist_len && (!oid_arr_len || !oid_arr_broken_check_len ||
2007+
!oid_arr || !oid_arr_broken_check)) {
2008+
PyErr_NoMemory();
2009+
snmp_free_pdu(pdu);
2010+
goto done;
2011+
}
2012+
20012013
for(varlist_ind = 0; varlist_ind < varlist_len; varlist_ind++) {
20022014

20032015
oid_arr[varlist_ind] = calloc(MAX_OID_LEN, sizeof(oid));
20042016
oid_arr_broken_check[varlist_ind] = calloc(MAX_OID_LEN, sizeof(oid));
20052017

2018+
if (!oid_arr[varlist_ind] || !oid_arr_broken_check[varlist_ind]) {
2019+
PyErr_NoMemory();
2020+
snmp_free_pdu(pdu);
2021+
goto done;
2022+
}
2023+
20062024
oid_arr_len[varlist_ind] = MAX_OID_LEN;
20072025
oid_arr_broken_check_len[varlist_ind] = MAX_OID_LEN;
20082026
}
@@ -2109,8 +2127,6 @@ netsnmp_walk(PyObject *self, PyObject *args)
21092127
vars != NULL;
21102128
vars = vars->next_variable, varlist_ind++) {
21112129

2112-
oid_arr_broken_check[varlist_ind] = calloc(MAX_OID_LEN, sizeof(oid));
2113-
21142130
oid_arr_broken_check_len[varlist_ind] = vars->name_length;
21152131
memcpy(oid_arr_broken_check[varlist_ind],
21162132
vars->name, vars->name_length * sizeof(oid));
@@ -2129,12 +2145,17 @@ netsnmp_walk(PyObject *self, PyObject *args)
21292145
} else {
21302146
newpdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
21312147

2148+
if (!newpdu) {
2149+
PyErr_NoMemory();
2150+
snmp_free_pdu(response);
2151+
response = NULL;
2152+
break;
2153+
}
2154+
21322155
for(vars = (response ? response->variables : NULL),
2133-
varlist_ind = 0,
2134-
oldvars = (pdu ? pdu->variables : NULL);
2156+
varlist_ind = 0;
21352157
vars && (varlist_ind < varlist_len);
2136-
vars = vars->next_variable, varlist_ind++,
2137-
oldvars = (oldvars ? oldvars->next_variable : NULL)) {
2158+
vars = vars->next_variable, varlist_ind++) {
21382159

21392160
if ((vars->name_length < oid_arr_len[varlist_ind]) ||
21402161
(memcmp(oid_arr[varlist_ind], vars->name,
@@ -2228,7 +2249,10 @@ application.
22282249
snmp_add_null_var(newpdu, vars->name,
22292250
vars->name_length);
22302251
}
2231-
pdu = newpdu;
2252+
if (notdone)
2253+
pdu = newpdu;
2254+
else
2255+
snmp_free_pdu(newpdu);
22322256
}
22332257
if (response)
22342258
snmp_free_pdu(response);
@@ -2244,20 +2268,24 @@ application.
22442268
/* propagate error */
22452269
if (verbose)
22462270
printf("error: walk response processing: unknown python error");
2247-
Py_DECREF(val_tuple);
2271+
Py_CLEAR(val_tuple);
22482272
}
22492273
}
22502274

22512275
done:
22522276
Py_XDECREF(varbinds);
22532277
SAFE_FREE(oid_arr_len);
22542278
SAFE_FREE(oid_arr_broken_check_len);
2255-
for(varlist_ind = 0; varlist_ind < varlist_len; varlist_ind ++) {
2256-
SAFE_FREE(oid_arr[varlist_ind]);
2257-
SAFE_FREE(oid_arr_broken_check[varlist_ind]);
2258-
}
2279+
if (oid_arr)
2280+
for(varlist_ind = 0; varlist_ind < varlist_len; varlist_ind ++)
2281+
SAFE_FREE(oid_arr[varlist_ind]);
2282+
if (oid_arr_broken_check)
2283+
for(varlist_ind = 0; varlist_ind < varlist_len; varlist_ind ++)
2284+
SAFE_FREE(oid_arr_broken_check[varlist_ind]);
22592285
SAFE_FREE(oid_arr);
22602286
SAFE_FREE(oid_arr_broken_check);
2287+
if (PyErr_Occurred())
2288+
return NULL;
22612289
return (val_tuple ? val_tuple : Py_BuildValue(""));
22622290
}
22632291

0 commit comments

Comments
 (0)