diff options
author | David Sommerseth <davids@redhat.com> | 2011-04-11 14:30:36 +0200 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2011-04-11 14:30:36 +0200 |
commit | abc7f912f66d41dd734a10900429d4cad9377da5 (patch) | |
tree | 91e26638c7d7a84fe750d037ca0231a34463ff30 | |
parent | 710766dc72260149bd78fd6168fbaf6838fc3d4f (diff) | |
download | python-ethtool-abc7f912f66d41dd734a10900429d4cad9377da5.tar.gz python-ethtool-abc7f912f66d41dd734a10900429d4cad9377da5.tar.xz python-ethtool-abc7f912f66d41dd734a10900429d4cad9377da5.zip |
Fixed several memory leaks
Several places python-ethtool leaked memory, mostly due to missing
Py_DECREF() calls on objects being put in to python lists (via
PyList_Append() calls).
This revealed an issue in addition where the IPv6 addresses pointers
in some cases could freed more times. This is fixed as well.
Signed-off-by: David Sommerseth <davids@redhat.com>
-rw-r--r-- | python-ethtool/etherinfo.c | 6 | ||||
-rw-r--r-- | python-ethtool/etherinfo_obj.c | 11 | ||||
-rw-r--r-- | python-ethtool/ethtool.c | 15 |
3 files changed, 22 insertions, 10 deletions
diff --git a/python-ethtool/etherinfo.c b/python-ethtool/etherinfo.c index 3d2072b..5539cf7 100644 --- a/python-ethtool/etherinfo.c +++ b/python-ethtool/etherinfo.c @@ -59,16 +59,14 @@ void free_ipv6addresses(struct ipv6address *ptr) { struct ipv6address *ipv6ptr = ptr; - if( !ptr ) { - return; - } - while( ipv6ptr ) { struct ipv6address *tmp = ipv6ptr->next; if( ipv6ptr->address ) { free(ipv6ptr->address); + ipv6ptr->address = NULL; } + memset(ipv6ptr, 0, sizeof(struct ipv6address)); free(ipv6ptr); ipv6ptr = tmp; } diff --git a/python-ethtool/etherinfo_obj.c b/python-ethtool/etherinfo_obj.c index aefb940..e1e03fe 100644 --- a/python-ethtool/etherinfo_obj.c +++ b/python-ethtool/etherinfo_obj.c @@ -167,6 +167,7 @@ PyObject *_ethtool_etherinfo_str(etherinfo_py *self) if( self->data->ethinfo->hwaddress ) { PyObject *tmp = PyString_FromFormat("\tMAC address: %s\n", self->data->ethinfo->hwaddress); PyString_Concat(&ret, tmp); + Py_DECREF(tmp); } if( self->data->ethinfo->ipv4_address ) { @@ -174,19 +175,21 @@ PyObject *_ethtool_etherinfo_str(etherinfo_py *self) self->data->ethinfo->ipv4_address, self->data->ethinfo->ipv4_netmask); if( self->data->ethinfo->ipv4_broadcast ) { - PyObject *tmp2 = PyString_FromFormat(" Broadcast: %s", + PyObject *tmp2 = PyString_FromFormat(" Broadcast: %s", self->data->ethinfo->ipv4_broadcast); PyString_Concat(&tmp, tmp2); + Py_DECREF(tmp2); } PyString_Concat(&tmp, PyString_FromString("\n")); PyString_Concat(&ret, tmp); + Py_DECREF(tmp); } if( self->data->ethinfo->ipv6_addresses ) { struct ipv6address *ipv6 = self->data->ethinfo->ipv6_addresses; PyObject *tmp = PyString_FromFormat("\tIPv6 addresses:\n"); PyString_Concat(&ret, tmp); - + Py_DECREF(tmp); for( ; ipv6; ipv6 = ipv6->next) { char scope[66]; @@ -194,6 +197,7 @@ PyObject *_ethtool_etherinfo_str(etherinfo_py *self) PyObject *addr = PyString_FromFormat("\t [%s] %s/%i\n", scope, ipv6->address, ipv6->netmask); PyString_Concat(&ret, addr); + Py_DECREF(addr); } } return ret; @@ -249,10 +253,10 @@ PyObject * _ethtool_etherinfo_get_ipv6_addresses(etherinfo_py *self, PyObject *n } PyTuple_SetItem(args, 0, ipv6_pydata); ipv6_pyobj = PyObject_CallObject((PyObject *)ðtool_etherinfoIPv6Type, args); + Py_DECREF(args); if( ipv6_pyobj ) { PyTuple_SetItem(ret, i++, ipv6_pyobj); _PyTuple_Resize(&ret, i+1); - Py_INCREF(ipv6_pyobj); } else { PyErr_SetString(PyExc_RuntimeError, "[INTERNAL] Failed to initialise the new " @@ -262,6 +266,7 @@ PyObject * _ethtool_etherinfo_get_ipv6_addresses(etherinfo_py *self, PyObject *n ipv6 = next; } _PyTuple_Resize(&ret, i); + self->data->ethinfo->ipv6_addresses = NULL; return ret; } diff --git a/python-ethtool/ethtool.c b/python-ethtool/ethtool.c index a29f052..60e407c 100644 --- a/python-ethtool/ethtool.c +++ b/python-ethtool/ethtool.c @@ -93,8 +93,11 @@ static PyObject *get_active_devices(PyObject *self __unused, PyObject *args __un ifr = ifc.ifc_req; for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) { if (!(ioctl(skfd, SIOCGIFFLAGS, ifr) < 0)) - if (ifr->ifr_flags & IFF_UP) - PyList_Append(list, PyString_FromString(ifr->ifr_name)); + if (ifr->ifr_flags & IFF_UP) { + PyObject *str = PyString_FromString(ifr->ifr_name); + PyList_Append(list, str); + Py_DECREF(str); + } ifr++; } @@ -118,6 +121,7 @@ static PyObject *get_devices(PyObject *self __unused, PyObject *args __unused) /* skip over first two lines */ ret = fgets(buffer, 256, fd); ret = fgets(buffer, 256, fd); while (!feof(fd)) { + PyObject *str; char *name = buffer; char *end = buffer; @@ -129,7 +133,10 @@ static PyObject *get_devices(PyObject *self __unused, PyObject *args __unused) *end = 0; /* terminate where colon was */ while (*name == ' ') name++; /* skip over leading whitespace if any */ - PyList_Append(list, PyString_FromString(name)); + + str = PyString_FromString(name); + PyList_Append(list, str); + Py_DECREF(str); } fclose(fd); return list; @@ -320,7 +327,9 @@ static PyObject *get_interfaces_info(PyObject *self __unused, PyObject *args) { PyObject *dev = PyObject_CallObject((PyObject *)ðtool_etherinfoType, args); if( dev ) { PyList_Append(devlist, dev); + Py_DECREF(dev); } + Py_DECREF(args); } } if( fetch_devs_len > 0 ) { |