On 29.08.2013 12:49, Daniel P. Berrange wrote: > From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> > > 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@xxxxxxxxxx> > --- > 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; While the above is correct as it fixes the libvirtd (sanitizes input). However, I don't think we need the following, esp. if we ever change the limit. The older client won't be able to pass more parameters whereas it currently can. > > 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<REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX>; > unsigned int flags; > }; Moreover, after you introduce this - won't XDR complain if we try to encode more than _MAX items? Michal -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list