From b88f552daa9be63938e79092f078ce06da185cb6 Mon Sep 17 00:00:00 2001 Message-Id: From: "Daniel P. Berrange" Date: Fri, 30 Aug 2013 11:16:03 +0100 Subject: [PATCH] Add bounds checking on virDomainMigrate*Params RPC calls (CVE-2013-4292) For https://bugzilla.redhat.com/show_bug.cgi?id=1002667 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 (cherry picked from commit fd6f6a48619eb221afeb1c5965537534cd54e01d) --- daemon/remote.c | 42 ++++++++++++++++++++++++++++++++++++++++++ src/remote/remote_driver.c | 42 ++++++++++++++++++++++++++++++++++++++++++ src/remote/remote_protocol.x | 15 +++++++++------ 3 files changed, 93 insertions(+), 6 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index 03d5557..a11ba94 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -4620,6 +4620,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; @@ -4671,6 +4678,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))) @@ -4726,6 +4740,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))) @@ -4790,6 +4811,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; @@ -4845,6 +4873,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))) @@ -4897,6 +4932,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; diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 71d0034..30f8f90 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -6037,6 +6037,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) { @@ -6096,6 +6103,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) { @@ -6171,6 +6185,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; @@ -6250,6 +6271,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; @@ -6315,6 +6343,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; @@ -6380,6 +6415,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; diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 7cfebdf..4262c34 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -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]; @@ -2770,7 +2773,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; unsigned int flags; }; @@ -2780,7 +2783,7 @@ struct remote_domain_migrate_begin3_params_ret { }; struct remote_domain_migrate_prepare3_params_args { - remote_typed_param params<>; + remote_typed_param params; opaque cookie_in; unsigned int flags; }; @@ -2791,7 +2794,7 @@ struct remote_domain_migrate_prepare3_params_ret { }; struct remote_domain_migrate_prepare_tunnel3_params_args { - remote_typed_param params<>; + remote_typed_param params; opaque cookie_in; unsigned int flags; }; @@ -2803,7 +2806,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; opaque cookie_in; unsigned int flags; }; @@ -2813,7 +2816,7 @@ struct remote_domain_migrate_perform3_params_ret { }; struct remote_domain_migrate_finish3_params_args { - remote_typed_param params<>; + remote_typed_param params; opaque cookie_in; unsigned int flags; int cancelled; @@ -2826,7 +2829,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; opaque cookie_in; unsigned int flags; int cancelled; -- 1.8.3.2