Skip to content

Commit 9ddf531

Browse files
committed
Fix memory leaks in get_interfaces_info()
The first half of get_interfaces_info() potentially allocates fetch_devs using calloc, setting fetch_devs_len to a value which may or may not be non-zero. In particular, given a tuple argument containing all non-strings, allocation occurs, but fetch_devs_len is set to zero, so it's not correct to use (fetch_devs_len > 0) as the condition for freeing the memory on the primary exit path, as this would leak fetch_devs (introduced in bfdcac6) There are also two error-handling paths that fail to free it (introduced in 4f0295f) Instead of this logic, simply initialize it to NULL, and pass it to free on every exit route of the second half of the function: free(NULL) is guaranteed to be a no-op. Found by Braňo Náter using the "cppcheck" static analyzer.
1 parent a950707 commit 9ddf531

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

python-ethtool/ethtool.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ static PyObject *get_ipaddress(PyObject *self __unused, PyObject *args)
247247
static PyObject *get_interfaces_info(PyObject *self __unused, PyObject *args) {
248248
PyObject *devlist = NULL, *ethinf_py = NULL;
249249
PyObject *inargs = NULL;
250-
char **fetch_devs;
250+
char **fetch_devs = NULL;
251251
int i = 0, fetch_devs_len = 0;
252252

253253
if (!PyArg_ParseTuple(args, "|O", &inargs)) {
@@ -301,12 +301,14 @@ static PyObject *get_interfaces_info(PyObject *self __unused, PyObject *args) {
301301
objdata = calloc(1, sizeof(struct etherinfo_obj_data));
302302
if( !objdata ) {
303303
PyErr_SetString(PyExc_OSError, strerror(errno));
304+
free(fetch_devs);
304305
return NULL;
305306
}
306307

307308
objdata->ethinfo = calloc(1, sizeof(struct etherinfo));
308309
if( !objdata->ethinfo ) {
309310
PyErr_SetString(PyExc_OSError, strerror(errno));
311+
free(fetch_devs);
310312
return NULL;
311313
}
312314

@@ -334,9 +336,8 @@ static PyObject *get_interfaces_info(PyObject *self __unused, PyObject *args) {
334336
Py_DECREF(args);
335337
}
336338
}
337-
if( fetch_devs_len > 0 ) {
338-
free(fetch_devs);
339-
}
339+
340+
free(fetch_devs);
340341

341342
return devlist;
342343
}

0 commit comments

Comments
 (0)