render / rpms / libvirt

Forked from rpms/libvirt 10 months ago
Clone
43fe83
From b88f552daa9be63938e79092f078ce06da185cb6 Mon Sep 17 00:00:00 2001
43fe83
Message-Id: <b88f552daa9be63938e79092f078ce06da185cb6.1377873639.git.jdenemar@redhat.com>
43fe83
From: "Daniel P. Berrange" <berrange@redhat.com>
43fe83
Date: Fri, 30 Aug 2013 11:16:03 +0100
43fe83
Subject: [PATCH] Add bounds checking on virDomainMigrate*Params RPC calls
43fe83
 (CVE-2013-4292)
43fe83
43fe83
For
43fe83
43fe83
  https://bugzilla.redhat.com/show_bug.cgi?id=1002667
43fe83
43fe83
The parameters for the virDomainMigrate*Params RPC calls were
43fe83
not bounds checks, meaning a malicious client can cause libvirtd
43fe83
to consume arbitrary memory
43fe83
43fe83
This issue was introduced in the 1.1.0 release of libvirt
43fe83
43fe83
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
43fe83
(cherry picked from commit fd6f6a48619eb221afeb1c5965537534cd54e01d)
43fe83
---
43fe83
 daemon/remote.c              | 42 ++++++++++++++++++++++++++++++++++++++++++
43fe83
 src/remote/remote_driver.c   | 42 ++++++++++++++++++++++++++++++++++++++++++
43fe83
 src/remote/remote_protocol.x | 15 +++++++++------
43fe83
 3 files changed, 93 insertions(+), 6 deletions(-)
43fe83
43fe83
diff --git a/daemon/remote.c b/daemon/remote.c
43fe83
index 03d5557..a11ba94 100644
43fe83
--- a/daemon/remote.c
43fe83
+++ b/daemon/remote.c
43fe83
@@ -4620,6 +4620,13 @@ remoteDispatchDomainMigrateBegin3Params(
43fe83
         goto cleanup;
43fe83
     }
43fe83
 
43fe83
+    if (args->params.params_len > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
43fe83
+        virReportError(VIR_ERR_RPC,
43fe83
+                       _("Too many migration parameters '%d' for limit '%d'"),
43fe83
+                       args->params.params_len, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
43fe83
+        goto cleanup;
43fe83
+    }
43fe83
+
43fe83
     if (!(dom = get_nonnull_domain(priv->conn, args->dom)))
43fe83
         goto cleanup;
43fe83
 
43fe83
@@ -4671,6 +4678,13 @@ remoteDispatchDomainMigratePrepare3Params(
43fe83
         goto cleanup;
43fe83
     }
43fe83
 
43fe83
+    if (args->params.params_len > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
43fe83
+        virReportError(VIR_ERR_RPC,
43fe83
+                       _("Too many migration parameters '%d' for limit '%d'"),
43fe83
+                       args->params.params_len, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
43fe83
+        goto cleanup;
43fe83
+    }
43fe83
+
43fe83
     if (!(params = remoteDeserializeTypedParameters(args->params.params_val,
43fe83
                                                     args->params.params_len,
43fe83
                                                     0, &nparams)))
43fe83
@@ -4726,6 +4740,13 @@ remoteDispatchDomainMigratePrepareTunnel3Params(
43fe83
         goto cleanup;
43fe83
     }
43fe83
 
43fe83
+    if (args->params.params_len > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
43fe83
+        virReportError(VIR_ERR_RPC,
43fe83
+                       _("Too many migration parameters '%d' for limit '%d'"),
43fe83
+                       args->params.params_len, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
43fe83
+        goto cleanup;
43fe83
+    }
43fe83
+
43fe83
     if (!(params = remoteDeserializeTypedParameters(args->params.params_val,
43fe83
                                                     args->params.params_len,
43fe83
                                                     0, &nparams)))
43fe83
@@ -4790,6 +4811,13 @@ remoteDispatchDomainMigratePerform3Params(
43fe83
         goto cleanup;
43fe83
     }
43fe83
 
43fe83
+    if (args->params.params_len > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
43fe83
+        virReportError(VIR_ERR_RPC,
43fe83
+                       _("Too many migration parameters '%d' for limit '%d'"),
43fe83
+                       args->params.params_len, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
43fe83
+        goto cleanup;
43fe83
+    }
43fe83
+
43fe83
     if (!(dom = get_nonnull_domain(priv->conn, args->dom)))
43fe83
         goto cleanup;
43fe83
 
43fe83
@@ -4845,6 +4873,13 @@ remoteDispatchDomainMigrateFinish3Params(
43fe83
         goto cleanup;
43fe83
     }
43fe83
 
43fe83
+    if (args->params.params_len > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
43fe83
+        virReportError(VIR_ERR_RPC,
43fe83
+                       _("Too many migration parameters '%d' for limit '%d'"),
43fe83
+                       args->params.params_len, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
43fe83
+        goto cleanup;
43fe83
+    }
43fe83
+
43fe83
     if (!(params = remoteDeserializeTypedParameters(args->params.params_val,
43fe83
                                                     args->params.params_len,
43fe83
                                                     0, &nparams)))
43fe83
@@ -4897,6 +4932,13 @@ remoteDispatchDomainMigrateConfirm3Params(
43fe83
         goto cleanup;
43fe83
     }
43fe83
 
43fe83
+    if (args->params.params_len > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
43fe83
+        virReportError(VIR_ERR_RPC,
43fe83
+                       _("Too many migration parameters '%d' for limit '%d'"),
43fe83
+                       args->params.params_len, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
43fe83
+        goto cleanup;
43fe83
+    }
43fe83
+
43fe83
     if (!(dom = get_nonnull_domain(priv->conn, args->dom)))
43fe83
         goto cleanup;
43fe83
 
43fe83
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
43fe83
index 71d0034..30f8f90 100644
43fe83
--- a/src/remote/remote_driver.c
43fe83
+++ b/src/remote/remote_driver.c
43fe83
@@ -6037,6 +6037,13 @@ remoteDomainMigrateBegin3Params(virDomainPtr domain,
43fe83
     make_nonnull_domain(&args.dom, domain);
43fe83
     args.flags = flags;
43fe83
 
43fe83
+    if (nparams > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
43fe83
+        virReportError(VIR_ERR_RPC,
43fe83
+                       _("Too many migration parameters '%d' for limit '%d'"),
43fe83
+                       nparams, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
43fe83
+        goto cleanup;
43fe83
+    }
43fe83
+
43fe83
     if (remoteSerializeTypedParameters(params, nparams,
43fe83
                                        &args.params.params_val,
43fe83
                                        &args.params.params_len) < 0) {
43fe83
@@ -6096,6 +6103,13 @@ remoteDomainMigratePrepare3Params(virConnectPtr dconn,
43fe83
     memset(&args, 0, sizeof(args));
43fe83
     memset(&ret, 0, sizeof(ret));
43fe83
 
43fe83
+    if (nparams > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
43fe83
+        virReportError(VIR_ERR_RPC,
43fe83
+                       _("Too many migration parameters '%d' for limit '%d'"),
43fe83
+                       nparams, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
43fe83
+        goto cleanup;
43fe83
+    }
43fe83
+
43fe83
     if (remoteSerializeTypedParameters(params, nparams,
43fe83
                                        &args.params.params_val,
43fe83
                                        &args.params.params_len) < 0) {
43fe83
@@ -6171,6 +6185,13 @@ remoteDomainMigratePrepareTunnel3Params(virConnectPtr dconn,
43fe83
     memset(&args, 0, sizeof(args));
43fe83
     memset(&ret, 0, sizeof(ret));
43fe83
 
43fe83
+    if (nparams > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
43fe83
+        virReportError(VIR_ERR_RPC,
43fe83
+                       _("Too many migration parameters '%d' for limit '%d'"),
43fe83
+                       nparams, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
43fe83
+        goto cleanup;
43fe83
+    }
43fe83
+
43fe83
     args.cookie_in.cookie_in_val = (char *)cookiein;
43fe83
     args.cookie_in.cookie_in_len = cookieinlen;
43fe83
     args.flags = flags;
43fe83
@@ -6250,6 +6271,13 @@ remoteDomainMigratePerform3Params(virDomainPtr dom,
43fe83
     memset(&args, 0, sizeof(args));
43fe83
     memset(&ret, 0, sizeof(ret));
43fe83
 
43fe83
+    if (nparams > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
43fe83
+        virReportError(VIR_ERR_RPC,
43fe83
+                       _("Too many migration parameters '%d' for limit '%d'"),
43fe83
+                       nparams, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
43fe83
+        goto cleanup;
43fe83
+    }
43fe83
+
43fe83
     make_nonnull_domain(&args.dom, dom);
43fe83
     args.dconnuri = dconnuri == NULL ? NULL : (char **) &dconnuri;
43fe83
     args.cookie_in.cookie_in_val = (char *)cookiein;
43fe83
@@ -6315,6 +6343,13 @@ remoteDomainMigrateFinish3Params(virConnectPtr dconn,
43fe83
     memset(&args, 0, sizeof(args));
43fe83
     memset(&ret, 0, sizeof(ret));
43fe83
 
43fe83
+    if (nparams > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
43fe83
+        virReportError(VIR_ERR_RPC,
43fe83
+                       _("Too many migration parameters '%d' for limit '%d'"),
43fe83
+                       nparams, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
43fe83
+        goto cleanup;
43fe83
+    }
43fe83
+
43fe83
     args.cookie_in.cookie_in_val = (char *)cookiein;
43fe83
     args.cookie_in.cookie_in_len = cookieinlen;
43fe83
     args.flags = flags;
43fe83
@@ -6380,6 +6415,13 @@ remoteDomainMigrateConfirm3Params(virDomainPtr domain,
43fe83
 
43fe83
     memset(&args, 0, sizeof(args));
43fe83
 
43fe83
+    if (nparams > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
43fe83
+        virReportError(VIR_ERR_RPC,
43fe83
+                       _("Too many migration parameters '%d' for limit '%d'"),
43fe83
+                       nparams, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
43fe83
+        goto cleanup;
43fe83
+    }
43fe83
+
43fe83
     make_nonnull_domain(&args.dom, domain);
43fe83
     args.cookie_in.cookie_in_len = cookieinlen;
43fe83
     args.cookie_in.cookie_in_val = (char *) cookiein;
43fe83
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
43fe83
index 7cfebdf..4262c34 100644
43fe83
--- a/src/remote/remote_protocol.x
43fe83
+++ b/src/remote/remote_protocol.x
43fe83
@@ -234,6 +234,9 @@ const REMOTE_DOMAIN_DISK_ERRORS_MAX = 256;
43fe83
  */
43fe83
 const REMOTE_NODE_MEMORY_PARAMETERS_MAX = 64;
43fe83
 
43fe83
+/* Upper limit on migrate parameters */
43fe83
+const REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX = 64;
43fe83
+
43fe83
 /* UUID.  VIR_UUID_BUFLEN definition comes from libvirt.h */
43fe83
 typedef opaque remote_uuid[VIR_UUID_BUFLEN];
43fe83
 
43fe83
@@ -2770,7 +2773,7 @@ struct remote_domain_fstrim_args {
43fe83
 
43fe83
 struct remote_domain_migrate_begin3_params_args {
43fe83
     remote_nonnull_domain dom;
43fe83
-    remote_typed_param params<>;
43fe83
+    remote_typed_param params<REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX>;
43fe83
     unsigned int flags;
43fe83
 };
43fe83
 
43fe83
@@ -2780,7 +2783,7 @@ struct remote_domain_migrate_begin3_params_ret {
43fe83
 };
43fe83
 
43fe83
 struct remote_domain_migrate_prepare3_params_args {
43fe83
-    remote_typed_param params<>;
43fe83
+    remote_typed_param params<REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX>;
43fe83
     opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>;
43fe83
     unsigned int flags;
43fe83
 };
43fe83
@@ -2791,7 +2794,7 @@ struct remote_domain_migrate_prepare3_params_ret {
43fe83
 };
43fe83
 
43fe83
 struct remote_domain_migrate_prepare_tunnel3_params_args {
43fe83
-    remote_typed_param params<>;
43fe83
+    remote_typed_param params<REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX>;
43fe83
     opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>;
43fe83
     unsigned int flags;
43fe83
 };
43fe83
@@ -2803,7 +2806,7 @@ struct remote_domain_migrate_prepare_tunnel3_params_ret {
43fe83
 struct remote_domain_migrate_perform3_params_args {
43fe83
     remote_nonnull_domain dom;
43fe83
     remote_string dconnuri;
43fe83
-    remote_typed_param params<>;
43fe83
+    remote_typed_param params<REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX>;
43fe83
     opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>;
43fe83
     unsigned int flags;
43fe83
 };
43fe83
@@ -2813,7 +2816,7 @@ struct remote_domain_migrate_perform3_params_ret {
43fe83
 };
43fe83
 
43fe83
 struct remote_domain_migrate_finish3_params_args {
43fe83
-    remote_typed_param params<>;
43fe83
+    remote_typed_param params<REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX>;
43fe83
     opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>;
43fe83
     unsigned int flags;
43fe83
     int cancelled;
43fe83
@@ -2826,7 +2829,7 @@ struct remote_domain_migrate_finish3_params_ret {
43fe83
 
43fe83
 struct remote_domain_migrate_confirm3_params_args {
43fe83
     remote_nonnull_domain dom;
43fe83
-    remote_typed_param params<>;
43fe83
+    remote_typed_param params<REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX>;
43fe83
     opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>;
43fe83
     unsigned int flags;
43fe83
     int cancelled;
43fe83
-- 
43fe83
1.8.3.2
43fe83