]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Add bounds checking on virDomainMigrate*Params RPC calls (CVE-2013-4292)
authorDaniel P. Berrange <berrange@redhat.com>
Mon, 19 Aug 2013 13:55:21 +0000 (14:55 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 29 Aug 2013 14:49:54 +0000 (15:49 +0100)
The parameters for the virDomainMigrate*Params RPC calls were
not bounds checks, meaning a malicious client can cause libvirtd
to consume arbitrary memory

This issue was introduced in the 1.1.0 release of libvirt

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit fd6f6a48619eb221afeb1c5965537534cd54e01d)

daemon/remote.c
src/remote/remote_driver.c
src/remote/remote_protocol.x

index cb362dad11c26402ff3653a6405078a6b835630f..36583ca79ab085eddc19ccdc42e64d9084c866aa 100644 (file)
@@ -4701,6 +4701,13 @@ remoteDispatchDomainMigrateBegin3Params(
         goto cleanup;
     }
 
+    if (args->params.params_len > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
+        virReportError(VIR_ERR_RPC,
+                       _("Too many migration parameters '%d' for limit '%d'"),
+                       args->params.params_len, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
+        goto cleanup;
+    }
+
     if (!(dom = get_nonnull_domain(priv->conn, args->dom)))
         goto cleanup;
 
@@ -4752,6 +4759,13 @@ remoteDispatchDomainMigratePrepare3Params(
         goto cleanup;
     }
 
+    if (args->params.params_len > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
+        virReportError(VIR_ERR_RPC,
+                       _("Too many migration parameters '%d' for limit '%d'"),
+                       args->params.params_len, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
+        goto cleanup;
+    }
+
     if (!(params = remoteDeserializeTypedParameters(args->params.params_val,
                                                     args->params.params_len,
                                                     0, &nparams)))
@@ -4809,6 +4823,13 @@ remoteDispatchDomainMigratePrepareTunnel3Params(
         goto cleanup;
     }
 
+    if (args->params.params_len > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
+        virReportError(VIR_ERR_RPC,
+                       _("Too many migration parameters '%d' for limit '%d'"),
+                       args->params.params_len, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
+        goto cleanup;
+    }
+
     if (!(params = remoteDeserializeTypedParameters(args->params.params_val,
                                                     args->params.params_len,
                                                     0, &nparams)))
@@ -4873,6 +4894,13 @@ remoteDispatchDomainMigratePerform3Params(
         goto cleanup;
     }
 
+    if (args->params.params_len > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
+        virReportError(VIR_ERR_RPC,
+                       _("Too many migration parameters '%d' for limit '%d'"),
+                       args->params.params_len, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
+        goto cleanup;
+    }
+
     if (!(dom = get_nonnull_domain(priv->conn, args->dom)))
         goto cleanup;
 
@@ -4928,6 +4956,13 @@ remoteDispatchDomainMigrateFinish3Params(
         goto cleanup;
     }
 
+    if (args->params.params_len > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
+        virReportError(VIR_ERR_RPC,
+                       _("Too many migration parameters '%d' for limit '%d'"),
+                       args->params.params_len, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
+        goto cleanup;
+    }
+
     if (!(params = remoteDeserializeTypedParameters(args->params.params_val,
                                                     args->params.params_len,
                                                     0, &nparams)))
@@ -4980,6 +5015,13 @@ remoteDispatchDomainMigrateConfirm3Params(
         goto cleanup;
     }
 
+    if (args->params.params_len > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
+        virReportError(VIR_ERR_RPC,
+                       _("Too many migration parameters '%d' for limit '%d'"),
+                       args->params.params_len, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
+        goto cleanup;
+    }
+
     if (!(dom = get_nonnull_domain(priv->conn, args->dom)))
         goto cleanup;
 
index 7f3e83332c355aa3187465457c8cd7669f2505e0..2d3cdce6eb50fca114b6af4d9cc788e7591bcf7f 100644 (file)
@@ -6064,6 +6064,13 @@ remoteDomainMigrateBegin3Params(virDomainPtr domain,
     make_nonnull_domain(&args.dom, domain);
     args.flags = flags;
 
+    if (nparams > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
+        virReportError(VIR_ERR_RPC,
+                       _("Too many migration parameters '%d' for limit '%d'"),
+                       nparams, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
+        goto cleanup;
+    }
+
     if (remoteSerializeTypedParameters(params, nparams,
                                        &args.params.params_val,
                                        &args.params.params_len) < 0) {
@@ -6123,6 +6130,13 @@ remoteDomainMigratePrepare3Params(virConnectPtr dconn,
     memset(&args, 0, sizeof(args));
     memset(&ret, 0, sizeof(ret));
 
+    if (nparams > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
+        virReportError(VIR_ERR_RPC,
+                       _("Too many migration parameters '%d' for limit '%d'"),
+                       nparams, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
+        goto cleanup;
+    }
+
     if (remoteSerializeTypedParameters(params, nparams,
                                        &args.params.params_val,
                                        &args.params.params_len) < 0) {
@@ -6198,6 +6212,13 @@ remoteDomainMigratePrepareTunnel3Params(virConnectPtr dconn,
     memset(&args, 0, sizeof(args));
     memset(&ret, 0, sizeof(ret));
 
+    if (nparams > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
+        virReportError(VIR_ERR_RPC,
+                       _("Too many migration parameters '%d' for limit '%d'"),
+                       nparams, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
+        goto cleanup;
+    }
+
     args.cookie_in.cookie_in_val = (char *)cookiein;
     args.cookie_in.cookie_in_len = cookieinlen;
     args.flags = flags;
@@ -6277,6 +6298,13 @@ remoteDomainMigratePerform3Params(virDomainPtr dom,
     memset(&args, 0, sizeof(args));
     memset(&ret, 0, sizeof(ret));
 
+    if (nparams > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
+        virReportError(VIR_ERR_RPC,
+                       _("Too many migration parameters '%d' for limit '%d'"),
+                       nparams, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
+        goto cleanup;
+    }
+
     make_nonnull_domain(&args.dom, dom);
     args.dconnuri = dconnuri == NULL ? NULL : (char **) &dconnuri;
     args.cookie_in.cookie_in_val = (char *)cookiein;
@@ -6342,6 +6370,13 @@ remoteDomainMigrateFinish3Params(virConnectPtr dconn,
     memset(&args, 0, sizeof(args));
     memset(&ret, 0, sizeof(ret));
 
+    if (nparams > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
+        virReportError(VIR_ERR_RPC,
+                       _("Too many migration parameters '%d' for limit '%d'"),
+                       nparams, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
+        goto cleanup;
+    }
+
     args.cookie_in.cookie_in_val = (char *)cookiein;
     args.cookie_in.cookie_in_len = cookieinlen;
     args.flags = flags;
@@ -6407,6 +6442,13 @@ remoteDomainMigrateConfirm3Params(virDomainPtr domain,
 
     memset(&args, 0, sizeof(args));
 
+    if (nparams > REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX) {
+        virReportError(VIR_ERR_RPC,
+                       _("Too many migration parameters '%d' for limit '%d'"),
+                       nparams, REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX);
+        goto cleanup;
+    }
+
     make_nonnull_domain(&args.dom, domain);
     args.cookie_in.cookie_in_len = cookieinlen;
     args.cookie_in.cookie_in_val = (char *) cookiein;
index 2e9dc1d6589f76bb57904b74b364b2a221675581..cb4fb8f440673e448aa36fac65a291b72213fd9c 100644 (file)
@@ -234,6 +234,9 @@ const REMOTE_DOMAIN_DISK_ERRORS_MAX = 256;
  */
 const REMOTE_NODE_MEMORY_PARAMETERS_MAX = 64;
 
+/* Upper limit on migrate parameters */
+const REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX = 64;
+
 /* UUID.  VIR_UUID_BUFLEN definition comes from libvirt.h */
 typedef opaque remote_uuid[VIR_UUID_BUFLEN];
 
@@ -2746,7 +2749,7 @@ struct remote_domain_fstrim_args {
 
 struct remote_domain_migrate_begin3_params_args {
     remote_nonnull_domain dom;
-    remote_typed_param params<>;
+    remote_typed_param params<REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX>;
     unsigned int flags;
 };
 
@@ -2756,7 +2759,7 @@ struct remote_domain_migrate_begin3_params_ret {
 };
 
 struct remote_domain_migrate_prepare3_params_args {
-    remote_typed_param params<>;
+    remote_typed_param params<REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX>;
     opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>;
     unsigned int flags;
 };
@@ -2767,7 +2770,7 @@ struct remote_domain_migrate_prepare3_params_ret {
 };
 
 struct remote_domain_migrate_prepare_tunnel3_params_args {
-    remote_typed_param params<>;
+    remote_typed_param params<REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX>;
     opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>;
     unsigned int flags;
 };
@@ -2779,7 +2782,7 @@ struct remote_domain_migrate_prepare_tunnel3_params_ret {
 struct remote_domain_migrate_perform3_params_args {
     remote_nonnull_domain dom;
     remote_string dconnuri;
-    remote_typed_param params<>;
+    remote_typed_param params<REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX>;
     opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>;
     unsigned int flags;
 };
@@ -2789,7 +2792,7 @@ struct remote_domain_migrate_perform3_params_ret {
 };
 
 struct remote_domain_migrate_finish3_params_args {
-    remote_typed_param params<>;
+    remote_typed_param params<REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX>;
     opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>;
     unsigned int flags;
     int cancelled;
@@ -2802,7 +2805,7 @@ struct remote_domain_migrate_finish3_params_ret {
 
 struct remote_domain_migrate_confirm3_params_args {
     remote_nonnull_domain dom;
-    remote_typed_param params<>;
+    remote_typed_param params<REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX>;
     opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>;
     unsigned int flags;
     int cancelled;