diff --git a/docs/misc/xenstore.txt b/docs/misc/xenstore.txt index 192d13264b..dba6471387 100644 --- a/docs/misc/xenstore.txt +++ b/docs/misc/xenstore.txt @@ -430,13 +430,14 @@ SET_FEATURE || to set a bit for a feature not being supported by the running Xenstore will be denied. Providing no with the GET_FEATURE command will return the features which are supported - by Xenstore. + by Xenstore for the domain issuing the command. SET_FEATURE for a domain will be rejected after the INTRODUCE - command for this domain has been sent to xenstored. + command for this domain has been sent to xenstored. This has the + effect that dom0 will always have all supported features enabled. - xenstored prevents the use of GET_FEATURE and SET_FEATURE other - than by dom0. + xenstored prevents the use of GET_FEATURE with a domid specified + and SET_FEATURE other than by dom0. GET_QUOTA [[|]|] | SET_QUOTA [|]|| diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c index 4786a2a82e..807a8e6710 100644 --- a/tools/xenstored/core.c +++ b/tools/xenstored/core.c @@ -2031,8 +2031,7 @@ static struct { { "SET_TARGET", do_set_target, XS_FLAG_PRIV }, [XS_RESET_WATCHES] = { "RESET_WATCHES", do_reset_watches }, [XS_DIRECTORY_PART] = { "DIRECTORY_PART", send_directory_part }, - [XS_GET_FEATURE] = - { "GET_FEATURE", do_get_feature, XS_FLAG_PRIV }, + [XS_GET_FEATURE] = { "GET_FEATURE", do_get_feature }, [XS_SET_FEATURE] = { "SET_FEATURE", do_set_feature, XS_FLAG_PRIV }, [XS_GET_QUOTA] = diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c index 1684f6dee7..b0b339f569 100644 --- a/tools/xenstored/domain.c +++ b/tools/xenstored/domain.c @@ -1323,10 +1323,17 @@ int do_get_feature(const void *ctx, struct connection *conn, char *result; n_args = get_strings(in, vec, ARRAY_SIZE(vec)); - if (n_args > 1) - return EINVAL; - if (n_args == 1) { + if (!n_args) { + features = conn->domain ? conn->domain->features + : XENSTORE_FEATURES; + } else { + if (domain_is_unprivileged(conn)) + return EACCES; + + if (n_args > 1) + return EINVAL; + domid = parse_domid(vec[0]); if (errno) return errno; @@ -1334,8 +1341,7 @@ int do_get_feature(const void *ctx, struct connection *conn, if (!domain) return ENOENT; features = domain->features; - } else - features = XENSTORE_FEATURES; + } result = talloc_asprintf(ctx, "%u", features); if (!result)