Skip to content

Commit abc7f91

Browse files
author
David Sommerseth
committed
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>
1 parent 710766d commit abc7f91

File tree

3 files changed

+22
-10
lines changed

3 files changed

+22
-10
lines changed

python-ethtool/etherinfo.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,14 @@
5959
void free_ipv6addresses(struct ipv6address *ptr) {
6060
struct ipv6address *ipv6ptr = ptr;
6161

62-
if( !ptr ) {
63-
return;
64-
}
65-
6662
while( ipv6ptr ) {
6763
struct ipv6address *tmp = ipv6ptr->next;
6864

6965
if( ipv6ptr->address ) {
7066
free(ipv6ptr->address);
67+
ipv6ptr->address = NULL;
7168
}
69+
memset(ipv6ptr, 0, sizeof(struct ipv6address));
7270
free(ipv6ptr);
7371
ipv6ptr = tmp;
7472
}

python-ethtool/etherinfo_obj.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,33 +167,37 @@ PyObject *_ethtool_etherinfo_str(etherinfo_py *self)
167167
if( self->data->ethinfo->hwaddress ) {
168168
PyObject *tmp = PyString_FromFormat("\tMAC address: %s\n", self->data->ethinfo->hwaddress);
169169
PyString_Concat(&ret, tmp);
170+
Py_DECREF(tmp);
170171
}
171172

172173
if( self->data->ethinfo->ipv4_address ) {
173174
PyObject *tmp = PyString_FromFormat("\tIPv4 address: %s/%i",
174175
self->data->ethinfo->ipv4_address,
175176
self->data->ethinfo->ipv4_netmask);
176177
if( self->data->ethinfo->ipv4_broadcast ) {
177-
PyObject *tmp2 = PyString_FromFormat(" Broadcast: %s",
178+
PyObject *tmp2 = PyString_FromFormat(" Broadcast: %s",
178179
self->data->ethinfo->ipv4_broadcast);
179180
PyString_Concat(&tmp, tmp2);
181+
Py_DECREF(tmp2);
180182
}
181183
PyString_Concat(&tmp, PyString_FromString("\n"));
182184
PyString_Concat(&ret, tmp);
185+
Py_DECREF(tmp);
183186
}
184187

185188
if( self->data->ethinfo->ipv6_addresses ) {
186189
struct ipv6address *ipv6 = self->data->ethinfo->ipv6_addresses;
187190
PyObject *tmp = PyString_FromFormat("\tIPv6 addresses:\n");
188191
PyString_Concat(&ret, tmp);
189-
192+
Py_DECREF(tmp);
190193
for( ; ipv6; ipv6 = ipv6->next) {
191194
char scope[66];
192195

193196
rtnl_scope2str(ipv6->scope, scope, 64);
194197
PyObject *addr = PyString_FromFormat("\t [%s] %s/%i\n",
195198
scope, ipv6->address, ipv6->netmask);
196199
PyString_Concat(&ret, addr);
200+
Py_DECREF(addr);
197201
}
198202
}
199203
return ret;
@@ -249,10 +253,10 @@ PyObject * _ethtool_etherinfo_get_ipv6_addresses(etherinfo_py *self, PyObject *n
249253
}
250254
PyTuple_SetItem(args, 0, ipv6_pydata);
251255
ipv6_pyobj = PyObject_CallObject((PyObject *)&ethtool_etherinfoIPv6Type, args);
256+
Py_DECREF(args);
252257
if( ipv6_pyobj ) {
253258
PyTuple_SetItem(ret, i++, ipv6_pyobj);
254259
_PyTuple_Resize(&ret, i+1);
255-
Py_INCREF(ipv6_pyobj);
256260
} else {
257261
PyErr_SetString(PyExc_RuntimeError,
258262
"[INTERNAL] Failed to initialise the new "
@@ -262,6 +266,7 @@ PyObject * _ethtool_etherinfo_get_ipv6_addresses(etherinfo_py *self, PyObject *n
262266
ipv6 = next;
263267
}
264268
_PyTuple_Resize(&ret, i);
269+
self->data->ethinfo->ipv6_addresses = NULL;
265270
return ret;
266271
}
267272

python-ethtool/ethtool.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,11 @@ static PyObject *get_active_devices(PyObject *self __unused, PyObject *args __un
9393
ifr = ifc.ifc_req;
9494
for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) {
9595
if (!(ioctl(skfd, SIOCGIFFLAGS, ifr) < 0))
96-
if (ifr->ifr_flags & IFF_UP)
97-
PyList_Append(list, PyString_FromString(ifr->ifr_name));
96+
if (ifr->ifr_flags & IFF_UP) {
97+
PyObject *str = PyString_FromString(ifr->ifr_name);
98+
PyList_Append(list, str);
99+
Py_DECREF(str);
100+
}
98101
ifr++;
99102
}
100103

@@ -118,6 +121,7 @@ static PyObject *get_devices(PyObject *self __unused, PyObject *args __unused)
118121
/* skip over first two lines */
119122
ret = fgets(buffer, 256, fd); ret = fgets(buffer, 256, fd);
120123
while (!feof(fd)) {
124+
PyObject *str;
121125
char *name = buffer;
122126
char *end = buffer;
123127

@@ -129,7 +133,10 @@ static PyObject *get_devices(PyObject *self __unused, PyObject *args __unused)
129133
*end = 0; /* terminate where colon was */
130134
while (*name == ' ')
131135
name++; /* skip over leading whitespace if any */
132-
PyList_Append(list, PyString_FromString(name));
136+
137+
str = PyString_FromString(name);
138+
PyList_Append(list, str);
139+
Py_DECREF(str);
133140
}
134141
fclose(fd);
135142
return list;
@@ -320,7 +327,9 @@ static PyObject *get_interfaces_info(PyObject *self __unused, PyObject *args) {
320327
PyObject *dev = PyObject_CallObject((PyObject *)&ethtool_etherinfoType, args);
321328
if( dev ) {
322329
PyList_Append(devlist, dev);
330+
Py_DECREF(dev);
323331
}
332+
Py_DECREF(args);
324333
}
325334
}
326335
if( fetch_devs_len > 0 ) {

0 commit comments

Comments
 (0)