diff options
author | Machon Gregory <mbgrego@tycho.ncsc.mil> | 2011-06-02 17:32:18 +0100 |
---|---|---|
committer | Machon Gregory <mbgrego@tycho.ncsc.mil> | 2011-06-02 17:32:18 +0100 |
commit | 8acc9d512e07e1134709cb0dd485853ef54a7873 (patch) | |
tree | 1d207a0e9d59ffe3efc17132c05e0faf7df7cfa9 | |
parent | 7b7866eb2689ba6334d4beb3e1a63afa376bab90 (diff) | |
download | xen-8acc9d512e07e1134709cb0dd485853ef54a7873.tar.gz xen-8acc9d512e07e1134709cb0dd485853ef54a7873.tar.bz2 xen-8acc9d512e07e1134709cb0dd485853ef54a7873.zip |
libxl: flask xsm support
Adds support for assigning a label to domains, obtaining and setting the
current enforcing mode, and loading a policy with xl command and libxl
header when the Flask XSM is in use. Adheres to the changes made by the
patch to remove exposure of libxenctrl/libxenstore headers via libxl.h.
Signed-Off-By: Machon Gregory <mbgrego@tycho.ncsc.mil>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
-rw-r--r-- | tools/libxl/Makefile | 2 | ||||
-rw-r--r-- | tools/libxl/libxl.c | 1 | ||||
-rw-r--r-- | tools/libxl/libxl.h | 8 | ||||
-rw-r--r-- | tools/libxl/libxl.idl | 3 | ||||
-rw-r--r-- | tools/libxl/libxl_flask.c | 71 | ||||
-rw-r--r-- | tools/libxl/xl.h | 3 | ||||
-rw-r--r-- | tools/libxl/xl_cmdimpl.c | 165 | ||||
-rw-r--r-- | tools/libxl/xl_cmdtable.c | 18 |
8 files changed, 261 insertions, 10 deletions
diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile index 50a65672b9..84ab76faaa 100644 --- a/tools/libxl/Makefile +++ b/tools/libxl/Makefile @@ -35,7 +35,7 @@ LIBXL_OBJS-$(CONFIG_IA64) += libxl_nocpuid.o LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \ libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o \ libxl_internal.o libxl_utils.o libxl_uuid.o $(LIBXL_OBJS-y) -LIBXL_OBJS += _libxl_types.o +LIBXL_OBJS += _libxl_types.o libxl_flask.o $(LIBXL_OBJS): CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) $(CFLAGS_libxenstore) $(CFLAGS_libblktapctl) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 83c566f438..f4f65c698c 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -342,6 +342,7 @@ static void xcinfo2xlinfo(const xc_domaininfo_t *xcinfo, { memcpy(&(xlinfo->uuid), xcinfo->handle, sizeof(xen_domain_handle_t)); xlinfo->domid = xcinfo->domain; + xlinfo->ssidref = xcinfo->ssidref; xlinfo->dying = !!(xcinfo->flags&XEN_DOMINF_dying); xlinfo->shutdown = !!(xcinfo->flags&XEN_DOMINF_shutdown); diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h index 95a7ba3a7b..1f37adc2e1 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -499,6 +499,14 @@ static inline int libxl_domid_valid_guest(uint32_t domid) return domid > 0 && domid < DOMID_FIRST_RESERVED; } +int libxl_flask_context_to_sid(libxl_ctx *ctx, char *buf, size_t len, + uint32_t *ssidref); +int libxl_flask_sid_to_context(libxl_ctx *ctx, uint32_t ssidref, char **buf, + size_t *len); +int libxl_flask_getenforce(libxl_ctx *ctx); +int libxl_flask_setenforce(libxl_ctx *ctx, int mode); +int libxl_flask_loadpolicy(libxl_ctx *ctx, void *policy, uint32_t size); + /* common paths */ const char *libxl_sbindir_path(void); const char *libxl_bindir_path(void); diff --git a/tools/libxl/libxl.idl b/tools/libxl/libxl.idl index 123079e7cf..71ad051699 100644 --- a/tools/libxl/libxl.idl +++ b/tools/libxl/libxl.idl @@ -89,6 +89,7 @@ libxl_button = Enumeration("button", [ libxl_dominfo = Struct("dominfo",[ ("uuid", libxl_uuid), ("domid", libxl_domid), + ("ssidref", uint32), ("running", bool), ("blocked", bool), ("paused", bool), @@ -138,7 +139,7 @@ libxl_domain_create_info = Struct("domain_create_info",[ ("hvm", bool), ("hap", bool), ("oos", bool), - ("ssidref", integer), + ("ssidref", uint32), ("name", string), ("uuid", libxl_uuid), ("xsdata", libxl_key_value_list), diff --git a/tools/libxl/libxl_flask.c b/tools/libxl/libxl_flask.c new file mode 100644 index 0000000000..a5d0b8a4ce --- /dev/null +++ b/tools/libxl/libxl_flask.c @@ -0,0 +1,71 @@ +/* + * + * Author: Machon Gregory, <mbgrego@tycho.ncsc.mil> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <xenctrl.h> + +#include "libxl.h" +#include "libxl_internal.h" + +int libxl_flask_context_to_sid(libxl_ctx *ctx, char *buf, size_t len, + uint32_t *ssidref) +{ + int rc; + + rc = xc_flask_context_to_sid(ctx->xch, buf, len, ssidref); + + return rc; +} + +int libxl_flask_sid_to_context(libxl_ctx *ctx, uint32_t ssidref, + char **buf, size_t *len) +{ + int rc; + char tmp[XC_PAGE_SIZE]; + + rc = xc_flask_sid_to_context(ctx->xch, ssidref, tmp, sizeof(tmp)); + + if (!rc) { + *len = strlen(tmp); + *buf = strdup(tmp); + } + + return rc; +} + +int libxl_flask_getenforce(libxl_ctx *ctx) +{ + int rc; + + rc = xc_flask_getenforce(ctx->xch); + + return rc; +} + +int libxl_flask_setenforce(libxl_ctx *ctx, int mode) +{ + int rc; + + rc = xc_flask_setenforce(ctx->xch, mode); + + return rc; +} + +int libxl_flask_loadpolicy(libxl_ctx *ctx, void *policy, uint32_t size) +{ + + int rc; + + rc = xc_flask_load(ctx->xch, policy, size); + + return rc; +} diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h index a1aa8ef9cc..bce135abb0 100644 --- a/tools/libxl/xl.h +++ b/tools/libxl/xl.h @@ -87,6 +87,9 @@ int main_cpupoolcpuadd(int argc, char **argv); int main_cpupoolcpuremove(int argc, char **argv); int main_cpupoolmigrate(int argc, char **argv); int main_cpupoolnumasplit(int argc, char **argv); +int main_getenforce(int argc, char **argv); +int main_setenforce(int argc, char **argv); +int main_loadpolicy(int argc, char **argv); void help(const char *command); diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index 6b8e9910cc..ddd3c64e6d 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -652,6 +652,19 @@ static void parse_config_data(const char *configfile_filename_report, libxl_init_create_info(c_info); + if (!xlu_cfg_get_string (config, "seclabel", &buf)) { + e = libxl_flask_context_to_sid(ctx, (char *)buf, strlen(buf), + &c_info->ssidref); + if (e) { + if (errno == ENOSYS) { + fprintf(stderr, "XSM Disabled: seclabel not supported\n"); + } else { + fprintf(stderr, "Invalid seclabel: %s\n", buf); + exit(1); + } + } + } + c_info->hvm = 0; if (!xlu_cfg_get_string (config, "builder", &buf) && !strncmp(buf, "hvm", strlen(buf))) @@ -2264,13 +2277,14 @@ static void list_domains_details(const libxl_dominfo *info, int nb_domain) } } -static void list_domains(int verbose, const libxl_dominfo *info, int nb_domain) +static void list_domains(int verbose, int context, const libxl_dominfo *info, int nb_domain) { int i; static const char shutdown_reason_letters[]= "-rscw"; printf("Name ID Mem VCPUs\tState\tTime(s)"); - if (verbose) printf(" UUID Reason-Code"); + if (verbose) printf(" UUID Reason-Code\tSecurity Label"); + if (context && !verbose) printf(" Security Label"); printf("\n"); for (i = 0; i < nb_domain; i++) { char *domname; @@ -2294,9 +2308,22 @@ static void list_domains(int verbose, const libxl_dominfo *info, int nb_domain) free(domname); if (verbose) { printf(" " LIBXL_UUID_FMT, LIBXL_UUID_BYTES(info[i].uuid)); - if (info[i].shutdown) printf(" %8x", shutdown_reason); - else printf(" %8s", "-"); - } + if (info[i].shutdown) printf(" %8x", shutdown_reason); + else printf(" %8s", "-"); + } + if (verbose || context) { + int rc; + size_t size; + char *buf; + rc = libxl_flask_sid_to_context(ctx, info[i].ssidref, &buf, + &size); + if (rc < 0) + printf(" -"); + else { + printf(" %s", buf); + free(buf); + } + } putchar('\n'); } } @@ -3032,12 +3059,14 @@ int main_reboot(int argc, char **argv) int main_list(int argc, char **argv) { int opt, verbose = 0; + int context = 0; int details = 0; int option_index = 0; static struct option long_options[] = { {"long", 0, 0, 'l'}, {"help", 0, 0, 'h'}, {"verbose", 0, 0, 'v'}, + {"context", 0, 0, 'Z'}, {0, 0, 0, 0} }; @@ -3046,7 +3075,7 @@ int main_list(int argc, char **argv) int nb_domain, rc; while (1) { - opt = getopt_long(argc, argv, "lvh", long_options, &option_index); + opt = getopt_long(argc, argv, "lvhZ", long_options, &option_index); if (opt == -1) break; @@ -3060,6 +3089,9 @@ int main_list(int argc, char **argv) case 'v': verbose = 1; break; + case 'Z': + context = 1; + break; default: fprintf(stderr, "option `%c' not supported.\n", optopt); break; @@ -3095,7 +3127,7 @@ int main_list(int argc, char **argv) if (details) list_domains_details(info, nb_domain); else - list_domains(verbose, info, nb_domain); + list_domains(verbose, context, info, nb_domain); free(info_free); @@ -5280,3 +5312,122 @@ out: return ret; } + +int main_getenforce(int argc, char **argv) +{ + int ret; + + ret = libxl_flask_getenforce(ctx); + + if (ret < 0) { + if (errno == ENOSYS) + printf("Flask XSM Disabled\n"); + else + fprintf(stderr, "Failed to get enforcing mode\n"); + } + else if (ret == 1) + printf("Enforcing\n"); + else if (ret == 0) + printf("Permissive\n"); + + return ret; +} + +int main_setenforce(int argc, char **argv) +{ + int ret, mode = -1; + const char *p = NULL; + + if (optind >= argc) { + help("setenforce"); + return 2; + } + + p = argv[optind]; + + if (!strcmp(p, "0")) + mode = 0; + else if (!strcmp(p, "1")) + mode = 1; + else if (!strcasecmp(p, "permissive")) + mode = 0; + else if (!strcasecmp(p, "enforcing")) + mode = 1; + else { + help("setenforce"); + return 2; + } + + ret = libxl_flask_setenforce(ctx, mode); + + if (ret) { + if (errno == ENOSYS) { + fprintf(stderr, "Flask XSM disabled\n"); + } + else + fprintf(stderr, "error occured while setting enforcing mode (%i)\n", ret); + } + + return ret; +} + +int main_loadpolicy(int argc, char **argv) +{ + const char *polFName; + int polFd = 0; + void *polMemCp = NULL; + struct stat info; + int ret; + + if (optind >= argc) { + help("loadpolicy"); + return 2; + } + + polFName = argv[optind]; + polFd = open(polFName, O_RDONLY); + if ( polFd < 0 ) { + fprintf(stderr, "Error occurred opening policy file '%s': %s\n", + polFName, strerror(errno)); + ret = -1; + goto done; + } + + ret = stat(polFName, &info); + if ( ret < 0 ) { + fprintf(stderr, "Error occurred retrieving information about" + "policy file '%s': %s\n", polFName, strerror(errno)); + goto done; + } + + polMemCp = malloc(info.st_size); + + ret = read(polFd, polMemCp, info.st_size); + if ( ret < 0 ) { + fprintf(stderr, "Unable to read new Flask policy file: %s\n", + strerror(errno)); + goto done; + } + + ret = libxl_flask_loadpolicy(ctx, polMemCp, info.st_size); + + if (ret < 0) { + if (errno == ENOSYS) { + fprintf(stderr, "Flask XSM disabled\n"); + } else { + errno = -ret; + fprintf(stderr, "Unable to load new Flask policy: %s\n", + strerror(errno)); + ret = -1; + } + } else { + printf("Successfully loaded policy.\n"); + } + +done: + free(polMemCp); + if ( polFd > 0 ) + close(polFd); + + return ret; +} diff --git a/tools/libxl/xl_cmdtable.c b/tools/libxl/xl_cmdtable.c index b14fb377f5..044c24d6b1 100644 --- a/tools/libxl/xl_cmdtable.c +++ b/tools/libxl/xl_cmdtable.c @@ -36,7 +36,8 @@ struct cmd_spec cmd_table[] = { "List information about all/some domains", "[options] [Domain]\n", "-l, --long Output all VM details\n" - "-v, --verbose Prints out UUIDs", + "-v, --verbose Prints out UUIDs and security context\n" + "-Z, --context Prints out security context" }, { "destroy", &main_destroy, @@ -364,6 +365,21 @@ struct cmd_spec cmd_table[] = { "Splits up the machine into one CPU pool per NUMA node", "", }, + { "getenforce", + &main_getenforce, + "Returns the current enforcing mode of the Flask Xen security module", + "", + }, + { "setenforce", + &main_setenforce, + "Sets the current enforcing mode of the Flask Xen security module", + "<1|0|Enforcing|Permissive>", + }, + { "loadpolicy", + &main_loadpolicy, + "Loads a new policy int the Flask Xen security module", + "<policy file>", + }, }; int cmdtable_len = sizeof(cmd_table)/sizeof(struct cmd_spec); |