[Libvir] handle PyTuple_New's malloc failure

Jim Meyering jim at meyering.net
Thu Jan 17 15:41:49 UTC 2008


python/libvir.c calls PyTuple_New, but doesn't handle the possibility
of a NULL return value.  Subsequent use of the result pointer in e.g.,
PyTuple_SetItem, would dereference it.

This fixes most of them, but leaves the ones in
virConnectCredCallbackWrapper untouched.  Fixing them
properly is not as easy, and IMHO will require actual testing.

In this patch, I combined each new test like this

  ((info = PyTuple_New(8)) == NULL)

with the preceding "if (c_retval < 0)", since the bodies would be the same.

Duplicating that 2-line body might look more readable,
depending on which side of the bed you get up on...
I can go either way.

Subject: [PATCH] python/libvir.c: Handle PyTuple_New's malloc failure.

---
 python/libvir.c |   27 ++++++++++++---------------
 1 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/python/libvir.c b/python/libvir.c
index 3b41dc1..13b809f 100644
--- a/python/libvir.c
+++ b/python/libvir.c
@@ -48,17 +48,16 @@ libvirt_virDomainBlockStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {

     if (!PyArg_ParseTuple(args, (char *)"Oz:virDomainBlockStats",
         &pyobj_domain,&path))
-	return(NULL);
+        return(NULL);
     domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);

     c_retval = virDomainBlockStats(domain, path, &stats, sizeof(stats));
-    if (c_retval < 0) {
+    if (c_retval < 0 || (info = PyTuple_New(5)) == NULL) {
         Py_INCREF(Py_None);
-	return(Py_None);
+        return(Py_None);
     }

-    /* convert to a Python tupple of long objects */
-    info = PyTuple_New(5);
+    /* convert to a Python tuple of long objects */
     PyTuple_SetItem(info, 0, PyLong_FromLongLong(stats.rd_req));
     PyTuple_SetItem(info, 1, PyLong_FromLongLong(stats.rd_bytes));
     PyTuple_SetItem(info, 2, PyLong_FromLongLong(stats.wr_req));
@@ -82,13 +81,12 @@ libvirt_virDomainInterfaceStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args)
     domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);

     c_retval = virDomainInterfaceStats(domain, path, &stats, sizeof(stats));
-    if (c_retval < 0) {
+    if (c_retval < 0 || (info = PyTuple_New(8)) == NULL) {
         Py_INCREF(Py_None);
-	return(Py_None);
+        return(Py_None);
     }

-    /* convert to a Python tupple of long objects */
-    info = PyTuple_New(8);
+    /* convert to a Python tuple of long objects */
     PyTuple_SetItem(info, 0, PyLong_FromLongLong(stats.rx_bytes));
     PyTuple_SetItem(info, 1, PyLong_FromLongLong(stats.rx_packets));
     PyTuple_SetItem(info, 2, PyLong_FromLongLong(stats.rx_errs));
@@ -114,12 +112,11 @@ libvirt_virGetLastError(PyObject *self ATTRIBUTE_UNUSED, PyObject *args ATTRIBUT
     virError err;
     PyObject *info;

-    if (virCopyLastError(&err) <= 0) {
+    if (virCopyLastError(&err) <= 0 || (info = PyTuple_New(9)) == NULL) {
         Py_INCREF(Py_None);
-	return(Py_None);
+        return(Py_None);
     }

-    info = PyTuple_New(9);
     PyTuple_SetItem(info, 0, PyInt_FromLong((long) err.code));
     PyTuple_SetItem(info, 1, PyInt_FromLong((long) err.domain));
     PyTuple_SetItem(info, 2, libvirt_constcharPtrWrap(err.message));
@@ -145,12 +142,12 @@ libvirt_virConnGetLastError(PyObject *self ATTRIBUTE_UNUSED, PyObject *args)
         return(NULL);
     conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn);

-    if (virConnCopyLastError(conn, &err) <= 0) {
+    if (virConnCopyLastError(conn, &err) <= 0
+        || (info = PyTuple_New(9)) == NULL) {
         Py_INCREF(Py_None);
-	return(Py_None);
+        return(Py_None);
     }

-    info = PyTuple_New(9);
     PyTuple_SetItem(info, 0, PyInt_FromLong((long) err.code));
     PyTuple_SetItem(info, 1, PyInt_FromLong((long) err.domain));
     PyTuple_SetItem(info, 2, libvirt_constcharPtrWrap(err.message));
--
1.5.4.rc3.14.g44397




More information about the libvir-list mailing list