Skip to content

Commit 5e8e829

Browse files
committed
Prevent crashes on bare Varbind arguments
1 parent 50be8a3 commit 5e8e829

2 files changed

Lines changed: 60 additions & 9 deletions

File tree

‎netsnmp/client_intf.c‎

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,8 +1527,12 @@ netsnmp_get(PyObject *self, PyObject *args)
15271527

15281528
if (varlist) {
15291529
PyObject *varlist_iter = PyObject_GetIter(varlist);
1530+
if (!varlist_iter) {
1531+
snmp_free_pdu(pdu);
1532+
goto done;
1533+
}
15301534

1531-
while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) {
1535+
while ((varbind = PyIter_Next(varlist_iter))) {
15321536
if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 ||
15331537
py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0)
15341538
{
@@ -1674,6 +1678,10 @@ netsnmp_get(PyObject *self, PyObject *args)
16741678

16751679
done:
16761680
SAFE_FREE(oid_arr);
1681+
if (PyErr_Occurred()) {
1682+
Py_XDECREF(val_tuple);
1683+
return NULL;
1684+
}
16771685
return (val_tuple ? val_tuple : Py_BuildValue(""));
16781686
}
16791687

@@ -1745,8 +1753,12 @@ netsnmp_getnext(PyObject *self, PyObject *args)
17451753

17461754
if (varlist) {
17471755
PyObject *varlist_iter = PyObject_GetIter(varlist);
1756+
if (!varlist_iter) {
1757+
snmp_free_pdu(pdu);
1758+
goto done;
1759+
}
17481760

1749-
while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) {
1761+
while ((varbind = PyIter_Next(varlist_iter))) {
17501762
if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 ||
17511763
py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0)
17521764
{
@@ -1894,6 +1906,10 @@ netsnmp_getnext(PyObject *self, PyObject *args)
18941906

18951907
done:
18961908
SAFE_FREE(oid_arr);
1909+
if (PyErr_Occurred()) {
1910+
Py_XDECREF(val_tuple);
1911+
return NULL;
1912+
}
18971913
return (val_tuple ? val_tuple : Py_BuildValue(""));
18981914
}
18991915

@@ -1978,8 +1994,12 @@ netsnmp_walk(PyObject *self, PyObject *args)
19781994

19791995
/* we need an initial count for memory allocation */
19801996
varlist_iter = PyObject_GetIter(varlist);
1997+
if (!varlist_iter) {
1998+
snmp_free_pdu(pdu);
1999+
goto done;
2000+
}
19812001
varlist_len = 0;
1982-
while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) {
2002+
while ((varbind = PyIter_Next(varlist_iter))) {
19832003
varlist_len++;
19842004
}
19852005
Py_DECREF(varlist_iter);
@@ -2236,7 +2256,7 @@ application.
22362256
/* propagate error */
22372257
if (verbose)
22382258
printf("error: walk response processing: unknown python error");
2239-
Py_DECREF(val_tuple);
2259+
Py_CLEAR(val_tuple);
22402260
}
22412261
}
22422262

@@ -2250,6 +2270,10 @@ application.
22502270
}
22512271
SAFE_FREE(oid_arr);
22522272
SAFE_FREE(oid_arr_broken_check);
2273+
if (PyErr_Occurred()) {
2274+
Py_XDECREF(val_tuple);
2275+
return NULL;
2276+
}
22532277
return (val_tuple ? val_tuple : Py_BuildValue(""));
22542278
}
22552279

@@ -2487,14 +2511,16 @@ netsnmp_getbulk(PyObject *self, PyObject *args)
24872511
/* propagate error */
24882512
if (verbose)
24892513
printf("error: getbulk response processing: unknown python error");
2490-
if (val_tuple)
2491-
Py_DECREF(val_tuple);
2492-
val_tuple = NULL;
2514+
Py_CLEAR(val_tuple);
24932515
}
24942516
}
24952517

24962518
done:
24972519
SAFE_FREE(oid_arr);
2520+
if (PyErr_Occurred()) {
2521+
Py_XDECREF(val_tuple);
2522+
return NULL;
2523+
}
24982524
return (val_tuple ? val_tuple : Py_BuildValue(""));
24992525
}
25002526

@@ -2503,7 +2529,7 @@ netsnmp_set(PyObject *self, PyObject *args)
25032529
{
25042530
PyObject *session;
25052531
PyObject *varlist;
2506-
PyObject *varbind;
2532+
PyObject *varbind = NULL;
25072533
PyObject *ret = NULL;
25082534
netsnmp_session *ss;
25092535
netsnmp_pdu *pdu, *response;
@@ -2551,8 +2577,12 @@ netsnmp_set(PyObject *self, PyObject *args)
25512577

25522578
if (varlist) {
25532579
PyObject *varlist_iter = PyObject_GetIter(varlist);
2580+
if (!varlist_iter) {
2581+
snmp_free_pdu(pdu);
2582+
goto done;
2583+
}
25542584

2555-
while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) {
2585+
while ((varbind = PyIter_Next(varlist_iter))) {
25562586
if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 ||
25572587
py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0)
25582588
{
@@ -2637,6 +2667,8 @@ netsnmp_set(PyObject *self, PyObject *args)
26372667
done:
26382668
Py_XDECREF(varbind);
26392669
SAFE_FREE(oid_arr);
2670+
if (PyErr_Occurred())
2671+
return NULL;
26402672
return (ret ? ret : Py_BuildValue(""));
26412673
}
26422674

‎netsnmp/tests/test.py‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,25 @@ def testFuncs(self):
248248

249249

250250
class SetTests(unittest.TestCase):
251+
def test_session_methods_reject_bare_varbind(self):
252+
session = netsnmp.Session(Version=2,
253+
DestHost='127.0.0.1',
254+
Community='public',
255+
Timeout=1000,
256+
Retries=0)
257+
varbind = netsnmp.Varbind('.1.3.6.1.2.1.1.3', '0', b'1', 'INTEGER')
258+
calls = ((TypeError, lambda: session.get(varbind)),
259+
(TypeError, lambda: session.getnext(varbind)),
260+
(TypeError, lambda: session.set(varbind)),
261+
(AttributeError, lambda: session.walk(varbind)),
262+
(AttributeError,
263+
lambda: session.getbulk(0, 1, varbind)))
264+
265+
for error_type, call in calls:
266+
with self.subTest(call=call):
267+
with self.assertRaises(error_type):
268+
call()
269+
251270
def testFuncs(self):
252271
print("\n-------------- SET Test Start ----------------------------\n")
253272

0 commit comments

Comments
 (0)