diff options
author | David Malcolm <dmalcolm@redhat.com> | 2013-01-15 15:19:34 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2013-01-15 15:19:34 -0500 |
commit | 9ddf5312fe4f890438153fe3d8d50ea61ef326a8 (patch) | |
tree | bdf7442d8f177cdf498f4a546e413e39c4b8a344 | |
parent | a95070733f068f9fa1f9e06ec98426164bedecc4 (diff) | |
download | python-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.c | 9 |
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; } |