summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2013-01-15 15:19:34 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2013-01-15 15:19:34 -0500
commit9ddf5312fe4f890438153fe3d8d50ea61ef326a8 (patch)
treebdf7442d8f177cdf498f4a546e413e39c4b8a344
parenta95070733f068f9fa1f9e06ec98426164bedecc4 (diff)
downloadpython-ethtool-9ddf5312fe4f890438153fe3d8d50ea61ef326a8.tar.gz
python-ethtool-9ddf5312fe4f890438153fe3d8d50ea61ef326a8.tar.xz
python-ethtool-9ddf5312fe4f890438153fe3d8d50ea61ef326a8.zip
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 bfdcac6b16806416a6c0295fcfad5d820595d88c) There are also two error-handling paths that fail to free it (introduced in 4f0295fca2cfd933f4b9b539d5505cb24e4d420c) 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.
-rw-r--r--python-ethtool/ethtool.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/python-ethtool/ethtool.c b/python-ethtool/ethtool.c
index d377531..997736c 100644
--- a/python-ethtool/ethtool.c
+++ b/python-ethtool/ethtool.c
@@ -247,7 +247,7 @@ static PyObject *get_ipaddress(PyObject *self __unused, PyObject *args)
static PyObject *get_interfaces_info(PyObject *self __unused, PyObject *args) {
PyObject *devlist = NULL, *ethinf_py = NULL;
PyObject *inargs = NULL;
- char **fetch_devs;
+ char **fetch_devs = NULL;
int i = 0, fetch_devs_len = 0;
if (!PyArg_ParseTuple(args, "|O", &inargs)) {
@@ -301,12 +301,14 @@ static PyObject *get_interfaces_info(PyObject *self __unused, PyObject *args) {
objdata = calloc(1, sizeof(struct etherinfo_obj_data));
if( !objdata ) {
PyErr_SetString(PyExc_OSError, strerror(errno));
+ free(fetch_devs);
return NULL;
}
objdata->ethinfo = calloc(1, sizeof(struct etherinfo));
if( !objdata->ethinfo ) {
PyErr_SetString(PyExc_OSError, strerror(errno));
+ free(fetch_devs);
return NULL;
}
@@ -334,9 +336,8 @@ static PyObject *get_interfaces_info(PyObject *self __unused, PyObject *args) {
Py_DECREF(args);
}
}
- if( fetch_devs_len > 0 ) {
- free(fetch_devs);
- }
+
+ free(fetch_devs);
return devlist;
}