]> xenbits.xensource.com Git - libvirt.git/commitdiff
remote: avoid null dereference on error
authorEric Blake <eblake@redhat.com>
Tue, 3 May 2011 17:24:23 +0000 (11:24 -0600)
committerEric Blake <eblake@redhat.com>
Wed, 4 May 2011 16:55:29 +0000 (10:55 -0600)
Clang found three instances of uninitialized use of nparams in
the cleanup path.  Unfortunately, one is a false positive: clang
couldn't see that ret->params.params_val is guaranteed to be
NULL unless allocated within a function, and that nparams is
guaranteed to be assigned prior to the allocation; hoisting the
assignment to nparams to be earlier in the function shuts up
that false positive.  But two of the reports also happened to
highlight a real bug - the error path can dereference NULL.

Regression introduced in commit 158ba873.

* daemon/remote.c (remoteDispatchDomainGetMemoryParameters)
(remoteDispatchDomainGetBlkioParameters): Don't clear fields if
array was not allocated.
(remoteDispatchDomainGetSchedulerParameters): Initialize nparams
earlier.

daemon/remote.c

index eedbc770fc1451b55acea56bd49b3996d61f9af4..214f7a43671a51f0e187651d535b2de2da845184 100644 (file)
@@ -886,7 +886,8 @@ remoteDispatchDomainGetSchedulerParameters(struct qemud_server *server ATTRIBUTE
 {
     virDomainPtr dom = NULL;
     virSchedParameterPtr params = NULL;
-    int i, nparams;
+    int i;
+    int nparams = args->nparams;
     int rv = -1;
 
     if (!conn) {
@@ -894,8 +895,6 @@ remoteDispatchDomainGetSchedulerParameters(struct qemud_server *server ATTRIBUTE
         goto cleanup;
     }
 
-    nparams = args->nparams;
-
     if (nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX) {
         virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
         goto cleanup;
@@ -2970,7 +2969,8 @@ remoteDispatchDomainGetMemoryParameters(struct qemud_server *server
 {
     virDomainPtr dom = NULL;
     virMemoryParameterPtr params = NULL;
-    int i, nparams;
+    int i;
+    int nparams = args->nparams;
     unsigned int flags;
     int rv = -1;
 
@@ -2979,7 +2979,6 @@ remoteDispatchDomainGetMemoryParameters(struct qemud_server *server
         goto cleanup;
     }
 
-    nparams = args->nparams;
     flags = args->flags;
 
     if (nparams > REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX) {
@@ -3060,9 +3059,11 @@ success:
 cleanup:
     if (rv < 0) {
         remoteDispatchError(rerr);
-        for (i = 0; i < nparams; i++)
-            VIR_FREE(ret->params.params_val[i].field);
-        VIR_FREE(ret->params.params_val);
+        if (ret->params.params_val) {
+            for (i = 0; i < nparams; i++)
+                VIR_FREE(ret->params.params_val[i].field);
+            VIR_FREE(ret->params.params_val);
+        }
     }
     if (dom)
         virDomainFree(dom);
@@ -3186,7 +3187,8 @@ remoteDispatchDomainGetBlkioParameters(struct qemud_server *server
 {
     virDomainPtr dom = NULL;
     virBlkioParameterPtr params = NULL;
-    int i, nparams;
+    int i;
+    int nparams = args->nparams;
     unsigned int flags;
     int rv = -1;
 
@@ -3195,7 +3197,6 @@ remoteDispatchDomainGetBlkioParameters(struct qemud_server *server
         goto cleanup;
     }
 
-    nparams = args->nparams;
     flags = args->flags;
 
     if (nparams > REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX) {
@@ -3276,9 +3277,11 @@ success:
 cleanup:
     if (rv < 0) {
         remoteDispatchError(rerr);
-        for (i = 0; i < nparams; i++)
-            VIR_FREE(ret->params.params_val[i].field);
-        VIR_FREE(ret->params.params_val);
+        if (ret->params.params_val) {
+            for (i = 0; i < nparams; i++)
+                VIR_FREE(ret->params.params_val[i].field);
+            VIR_FREE(ret->params.params_val);
+        }
     }
     VIR_FREE(params);
     if (dom)