diff options
Diffstat (limited to 'tools')
-rwxr-xr-x | tools/hotplug/Linux/init.d/xend | 4 | ||||
-rw-r--r-- | tools/libxc/xc_flask.c | 357 | ||||
-rw-r--r-- | tools/libxc/xenctrl.h | 26 | ||||
-rw-r--r-- | tools/libxl/libxl.c | 4 | ||||
-rw-r--r-- | tools/libxl/libxl_device.c | 77 | ||||
-rw-r--r-- | tools/libxl/libxl_internal.h | 4 | ||||
-rw-r--r-- | tools/python/xen/lowlevel/xc/xc.c | 251 |
7 files changed, 689 insertions, 34 deletions
diff --git a/tools/hotplug/Linux/init.d/xend b/tools/hotplug/Linux/init.d/xend index 9ffbf55432..985db0c57c 100755 --- a/tools/hotplug/Linux/init.d/xend +++ b/tools/hotplug/Linux/init.d/xend @@ -37,6 +37,10 @@ function await_daemons_up case "$1" in start) + if [ -z "`ps -C xenconsoled -o pid=`" ]; then + echo "xencommons should be started first." + exit 1 + fi mkdir -p /var/lock/subsys touch /var/lock/subsys/xend xend start diff --git a/tools/libxc/xc_flask.c b/tools/libxc/xc_flask.c index 6982445b9c..12cb001dba 100644 --- a/tools/libxc/xc_flask.c +++ b/tools/libxc/xc_flask.c @@ -8,6 +8,24 @@ */ #include "xc_private.h" +#include <unistd.h> +#include <stdio.h> +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <stdint.h> +#include <sys/ioctl.h> +#include <stdint.h> + +#define OCON_PIRQ_STR "pirq" +#define OCON_IOPORT_STR "ioport" +#define OCON_IOMEM_STR "iomem" +#define OCON_DEVICE_STR "pcidevice" +#define INITCONTEXTLEN 256 int xc_flask_op(xc_interface *xch, flask_op_t *op) { @@ -35,6 +53,345 @@ int xc_flask_op(xc_interface *xch, flask_op_t *op) return ret; } +int xc_flask_load(xc_interface *xc_handle, char *buf, uint32_t size) +{ + int err; + flask_op_t op; + + op.cmd = FLASK_LOAD; + op.buf = buf; + op.size = size; + + if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) + return err; + + return 0; +} + +int xc_flask_context_to_sid(xc_interface *xc_handle, char *buf, uint32_t size, uint32_t *sid) +{ + int err; + flask_op_t op; + + op.cmd = FLASK_CONTEXT_TO_SID; + op.buf = buf; + op.size = size; + + if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) + return err; + + sscanf(buf, "%u", sid); + + return 0; +} + +int xc_flask_sid_to_context(xc_interface *xc_handle, int sid, char *buf, uint32_t size) +{ + int err; + flask_op_t op; + + op.cmd = FLASK_SID_TO_CONTEXT; + op.buf = buf; + op.size = size; + + snprintf(buf, size, "%u", sid); + + if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) + return err; + + return 0; +} + +int xc_flask_getenforce(xc_interface *xc_handle) +{ + int err; + flask_op_t op; + char buf[20]; + int size = 20; + int mode; + + op.cmd = FLASK_GETENFORCE; + op.buf = buf; + op.size = size; + + if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) + return err; + + sscanf(buf, "%i", &mode); + + return mode; +} + +int xc_flask_setenforce(xc_interface *xc_handle, int mode) +{ + int err; + flask_op_t op; + char buf[20]; + int size = 20; + + op.cmd = FLASK_SETENFORCE; + op.buf = buf; + op.size = size; + + snprintf(buf, size, "%i", mode); + + if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) + return err; + + return 0; +} + +static int xc_flask_add(xc_interface *xc_handle, char *cat, char *arg, char *scontext) +{ + char buf[512]; + flask_op_t op; + + memset(buf, 0, 512); + snprintf(buf, 512, "%s %255s %s", cat, scontext, arg); + op.cmd = FLASK_ADD_OCONTEXT; + op.buf = buf; + op.size = 512; + + return xc_flask_op(xc_handle, &op); +} + +int xc_flask_add_pirq(xc_interface *xc_handle, unsigned int pirq, char *scontext) +{ + char arg[16]; + + snprintf(arg, 16, "%u", pirq); + return xc_flask_add(xc_handle, OCON_PIRQ_STR, arg, scontext); +} + +int xc_flask_add_ioport(xc_interface *xc_handle, unsigned long low, unsigned long high, + char *scontext) +{ + char arg[64]; + + snprintf(arg, 64, "%lu %lu", low, high); + return xc_flask_add(xc_handle, OCON_IOPORT_STR, arg, scontext); +} + +int xc_flask_add_iomem(xc_interface *xc_handle, unsigned long low, unsigned long high, + char *scontext) +{ + char arg[64]; + + snprintf(arg, 64, "%lu %lu", low, high); + return xc_flask_add(xc_handle, OCON_IOMEM_STR, arg, scontext); +} + +int xc_flask_add_device(xc_interface *xc_handle, unsigned long device, char *scontext) +{ + char arg[32]; + + snprintf(arg, 32, "%lu", device); + return xc_flask_add(xc_handle, OCON_DEVICE_STR, arg, scontext); +} + +static int xc_flask_del(xc_interface *xc_handle, char *cat, char *arg) +{ + char buf[256]; + flask_op_t op; + + memset(buf, 0, 256); + snprintf(buf, 256, "%s %s", cat, arg); + op.cmd = FLASK_DEL_OCONTEXT; + op.buf = buf; + op.size = 256; + + return xc_flask_op(xc_handle, &op); +} + +int xc_flask_del_pirq(xc_interface *xc_handle, unsigned int pirq) +{ + char arg[16]; + + snprintf(arg, 16, "%u", pirq); + return xc_flask_del(xc_handle, OCON_PIRQ_STR, arg); +} + +int xc_flask_del_ioport(xc_interface *xc_handle, unsigned long low, unsigned long high) +{ + char arg[64]; + + snprintf(arg, 64, "%lu %lu", low, high); + return xc_flask_del(xc_handle, OCON_IOPORT_STR, arg); +} + +int xc_flask_del_iomem(xc_interface *xc_handle, unsigned long low, unsigned long high) +{ + char arg[64]; + + snprintf(arg, 64, "%lu %lu", low, high); + return xc_flask_del(xc_handle, OCON_IOMEM_STR, arg); +} + +int xc_flask_del_device(xc_interface *xc_handle, unsigned long device) +{ + char arg[32]; + + snprintf(arg, 32, "%lu", device); + return xc_flask_del(xc_handle, OCON_DEVICE_STR, arg); +} + +int xc_flask_access(xc_interface *xc_handle, const char *scon, const char *tcon, + uint16_t tclass, uint32_t req, + uint32_t *allowed, uint32_t *decided, + uint32_t *auditallow, uint32_t *auditdeny, + uint32_t *seqno) +{ +/* maximum number of digits in a 16-bit decimal number: */ +#define MAX_SHORT_DEC_LEN 5 + + char *buf; + int bufLen; + int err; + flask_op_t op; + uint32_t dummy_allowed; + uint32_t dummy_decided; + uint32_t dummy_auditallow; + uint32_t dummy_auditdeny; + uint32_t dummy_seqno; + + if (!allowed) + allowed = &dummy_allowed; + if (!decided) + decided = &dummy_decided; + if (!auditallow) + auditallow = &dummy_auditallow; + if (!auditdeny) + auditdeny = &dummy_auditdeny; + if (!seqno) + seqno = &dummy_seqno; + + if (!scon) + return -EINVAL; + if (!tcon) + return -EINVAL; + + bufLen = strlen(scon) + 1 + strlen(tcon) + 1 + + MAX_SHORT_DEC_LEN + 1 + + sizeof(req)*2 + 1; + buf = malloc(bufLen); + snprintf(buf, bufLen, "%s %s %hu %x", scon, tcon, tclass, req); + + op.cmd = FLASK_ACCESS; + op.buf = buf; + op.size = strlen(buf)+1; + + if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) + { + free(buf); + return err; + } + + if (sscanf(op.buf, "%x %x %x %x %u", + allowed, decided, + auditallow, auditdeny, + seqno) != 5) { + err = -EILSEQ; + } + + err = ((*allowed & req) == req)? 0 : -EPERM; + + return err; + +} + +int xc_flask_avc_hashstats(xc_interface *xc_handle, char *buf, int size) +{ + int err; + flask_op_t op; + + op.cmd = FLASK_AVC_HASHSTATS; + op.buf = buf; + op.size = size; + + if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) + { + free(buf); + return err; + } + + return 0; +} + +int xc_flask_avc_cachestats(xc_interface *xc_handle, char *buf, int size) +{ + int err; + flask_op_t op; + + op.cmd = FLASK_AVC_CACHESTATS; + op.buf = buf; + op.size = size; + + if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) + { + free(buf); + return err; + } + + return 0; +} + +int xc_flask_policyvers(xc_interface *xc_handle, char *buf, int size) +{ + int err; + flask_op_t op; + + op.cmd = FLASK_POLICYVERS; + op.buf = buf; + op.size = size; + + if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) + { + free(buf); + return err; + } + + return 0; +} + +int xc_flask_getavc_threshold(xc_interface *xc_handle) +{ + int err; + flask_op_t op; + char buf[20]; + int size = 20; + int threshold; + + op.cmd = FLASK_GETAVC_THRESHOLD; + op.buf = buf; + op.size = size; + + if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) + return err; + + sscanf(buf, "%i", &threshold); + + return threshold; +} + +int xc_flask_setavc_threshold(xc_interface *xc_handle, int threshold) +{ + int err; + flask_op_t op; + char buf[20]; + int size = 20; + + op.cmd = FLASK_SETAVC_THRESHOLD; + op.buf = buf; + op.size = size; + + snprintf(buf, size, "%i", threshold); + + if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) + return err; + + return 0; +} + /* * Local variables: * mode: C diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 705df1d2ff..b6c0df35eb 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -1517,6 +1517,32 @@ int xc_memshr_debug_gref(xc_interface *xch, uint32_t domid, grant_ref_t gref); +int xc_flask_load(xc_interface *xc_handle, char *buf, uint32_t size); +int xc_flask_context_to_sid(xc_interface *xc_handle, char *buf, uint32_t size, uint32_t *sid); +int xc_flask_sid_to_context(xc_interface *xc_handle, int sid, char *buf, uint32_t size); +int xc_flask_getenforce(xc_interface *xc_handle); +int xc_flask_setenforce(xc_interface *xc_handle, int mode); +int xc_flask_add_pirq(xc_interface *xc_handle, unsigned int pirq, char *scontext); +int xc_flask_add_ioport(xc_interface *xc_handle, unsigned long low, unsigned long high, + char *scontext); +int xc_flask_add_iomem(xc_interface *xc_handle, unsigned long low, unsigned long high, + char *scontext); +int xc_flask_add_device(xc_interface *xc_handle, unsigned long device, char *scontext); +int xc_flask_del_pirq(xc_interface *xc_handle, unsigned int pirq); +int xc_flask_del_ioport(xc_interface *xc_handle, unsigned long low, unsigned long high); +int xc_flask_del_iomem(xc_interface *xc_handle, unsigned long low, unsigned long high); +int xc_flask_del_device(xc_interface *xc_handle, unsigned long device); +int xc_flask_access(xc_interface *xc_handle, const char *scon, const char *tcon, + uint16_t tclass, uint32_t req, + uint32_t *allowed, uint32_t *decided, + uint32_t *auditallow, uint32_t *auditdeny, + uint32_t *seqno); +int xc_flask_avc_cachestats(xc_interface *xc_handle, char *buf, int size); +int xc_flask_policyvers(xc_interface *xc_handle, char *buf, int size); +int xc_flask_avc_hashstats(xc_interface *xc_handle, char *buf, int size); +int xc_flask_getavc_threshold(xc_interface *xc_handle); +int xc_flask_setavc_threshold(xc_interface *xc_handle, int threshold); + struct elf_binary; void xc_elf_set_logfile(struct xc_interface *xch, struct elf_binary *elf, int verbose); diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index ebcdb3d040..2563c91cc6 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -2381,7 +2381,7 @@ int libxl_device_pci_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_pci /* TODO: check if the device can be assigned */ - libxl_device_pci_flr(ctx, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); + libxl_device_pci_reset(ctx, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); stubdomid = libxl_get_stubdom_id(ctx, domid); if (stubdomid != 0) { @@ -2551,7 +2551,7 @@ skip1: fclose(f); } out: - libxl_device_pci_flr(ctx, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); + libxl_device_pci_reset(ctx, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); if (!libxl_is_stubdom(ctx, domid, NULL)) { rc = xc_deassign_device(ctx->xch, domid, pcidev->value); diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c index 090303b746..89c92db592 100644 --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -22,6 +22,8 @@ #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> +#include <fcntl.h> + #include "libxl.h" #include "libxl_internal.h" @@ -389,22 +391,36 @@ int libxl_device_del(struct libxl_ctx *ctx, libxl_device *dev, int wait) return 0; } -int libxl_device_pci_flr(struct libxl_ctx *ctx, unsigned int domain, unsigned int bus, +int libxl_device_pci_reset(struct libxl_ctx *ctx, unsigned int domain, unsigned int bus, unsigned int dev, unsigned int func) { - char *do_flr = "/sys/bus/pci/drivers/pciback/do_flr"; - FILE *fd; - - fd = fopen(do_flr, "w"); - if (fd != NULL) { - fprintf(fd, PCI_BDF, domain, bus, dev, func); - fclose(fd); - return 0; + char *reset = "/sys/bus/pci/drivers/pciback/do_flr"; + int fd, rc; + + fd = open(reset, O_WRONLY); + if (fd > 0) { + char *buf = libxl_sprintf(ctx, PCI_BDF, domain, bus, dev, func); + rc = write(fd, buf, strlen(buf)); + if (rc < 0) + XL_LOG(ctx, XL_LOG_ERROR, "write to %s returned %d", reset, rc); + close(fd); + return rc < 0 ? rc : 0; + } + if (errno != ENOENT) + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access pciback path %s", reset); + reset = libxl_sprintf(ctx, "/sys/bus/pci/devices/"PCI_BDF"/reset", domain, bus, dev, func); + fd = open(reset, O_WRONLY); + if (fd > 0) { + rc = write(fd, "1", 1); + if (rc < 0) + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "write to %s returned %d", reset, rc); + close(fd); + return rc < 0 ? rc : 0; } if (errno == ENOENT) { - XL_LOG(ctx, XL_LOG_ERROR, "Pciback doesn't support do_flr, cannot flr the device"); + XL_LOG(ctx, XL_LOG_ERROR, "The kernel doesn't support PCI device reset from sysfs"); } else { - XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access pciback path %s", do_flr); + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access reset path %s", reset); } return -1; } @@ -418,7 +434,7 @@ int libxl_wait_for_device_model(struct libxl_ctx *ctx, char *path; char *p; unsigned int len; - int rc; + int rc = 0; struct xs_handle *xsh; int nfds; fd_set rfds; @@ -432,28 +448,29 @@ int libxl_wait_for_device_model(struct libxl_ctx *ctx, tv.tv_sec = LIBXL_DEVICE_MODEL_START_TIMEOUT; tv.tv_usec = 0; nfds = xs_fileno(xsh) + 1; - while (tv.tv_sec > 0) { + while (rc > 0 || (!rc && tv.tv_sec > 0)) { + p = xs_read(xsh, XBT_NULL, path, &len); + if (p && (!state || !strcmp(state, p))) { + free(p); + xs_unwatch(xsh, path, path); + xs_daemon_close(xsh); + if (check_callback) { + rc = check_callback(ctx, check_callback_userdata); + if (rc) return rc; + } + return 0; + } + free(p); +again: FD_ZERO(&rfds); FD_SET(xs_fileno(xsh), &rfds); - if (select(nfds, &rfds, NULL, NULL, &tv) > 0) { + rc = select(nfds, &rfds, NULL, NULL, &tv); + if (rc > 0) { l = xs_read_watch(xsh, &num); - if (l != NULL) { + if (l != NULL) free(l); - p = xs_read(xsh, XBT_NULL, path, &len); - if (!p) - continue; - if (!state || !strcmp(state, p)) { - free(p); - xs_unwatch(xsh, path, path); - xs_daemon_close(xsh); - if (check_callback) { - rc = check_callback(ctx, check_callback_userdata); - if (rc) return rc; - } - return 0; - } - free(p); - } + else + goto again; } } xs_unwatch(xsh, path, path); diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 72ffd54a47..29dd2661a3 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -162,8 +162,8 @@ int libxl_wait_for_device_model(struct libxl_ctx *ctx, void *userdata), void *check_callback_userdata); int libxl_wait_for_backend(struct libxl_ctx *ctx, char *be_path, char *state); -int libxl_device_pci_flr(struct libxl_ctx *ctx, unsigned int domain, unsigned int bus, - unsigned int dev, unsigned int func); +int libxl_device_pci_reset(struct libxl_ctx *ctx, unsigned int domain, unsigned int bus, + unsigned int dev, unsigned int func); /* from xenguest (helper */ int hvm_build_set_params(xc_interface *handle, uint32_t domid, diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 13704249b5..6e9d3e1ac5 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -34,6 +34,8 @@ #define PKG "xen.lowlevel.xc" #define CLS "xc" +#define FLASK_CTX_LEN 1024 + static PyObject *xc_error_obj, *zero; typedef struct { @@ -2078,6 +2080,202 @@ static PyObject *pyxc_cpupool_freeinfo(XcObject *self) return cpumap_to_cpulist(cpumap); } +static PyObject *pyflask_context_to_sid(PyObject *self, PyObject *args, + PyObject *kwds) +{ + xc_interface *xc_handle; + char *ctx; + char *buf; + uint32_t len; + uint32_t sid; + int ret; + + static char *kwd_list[] = { "context", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list, + &ctx) ) + return NULL; + + len = strlen(ctx); + + buf = malloc(len); + if (!buf) { + errno = -ENOMEM; + PyErr_SetFromErrno(xc_error_obj); + } + + memcpy(buf, ctx, len); + + xc_handle = xc_interface_open(0,0,0); + if (!xc_handle) { + free(buf); + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_flask_context_to_sid(xc_handle, buf, len, &sid); + + xc_interface_close(xc_handle); + + free(buf); + + if ( ret != 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return PyInt_FromLong(sid); +} + +static PyObject *pyflask_sid_to_context(PyObject *self, PyObject *args, + PyObject *kwds) +{ + xc_interface *xc_handle; + uint32_t sid; + char ctx[FLASK_CTX_LEN]; + uint32_t ctx_len = FLASK_CTX_LEN; + int ret; + + static char *kwd_list[] = { "sid", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, + &sid) ) + return NULL; + + xc_handle = xc_interface_open(0,0,0); + if (!xc_handle) { + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_flask_sid_to_context(xc_handle, sid, ctx, ctx_len); + + xc_interface_close(xc_handle); + + if ( ret != 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return Py_BuildValue("s", ctx, ctx_len); +} + +static PyObject *pyflask_load(PyObject *self, PyObject *args, PyObject *kwds) +{ + xc_interface *xc_handle; + char *policy; + uint32_t len; + int ret; + + static char *kwd_list[] = { "policy", NULL }; + + if( !PyArg_ParseTupleAndKeywords(args, kwds, "s#", kwd_list, &policy, &len) ) + return NULL; + + xc_handle = xc_interface_open(0,0,0); + if (!xc_handle) { + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_flask_load(xc_handle, policy, len); + + xc_interface_close(xc_handle); + + if ( ret != 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return Py_BuildValue("i", ret); +} + +static PyObject *pyflask_getenforce(PyObject *self) +{ + xc_interface *xc_handle; + int ret; + + xc_handle = xc_interface_open(0,0,0); + if (!xc_handle) { + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_flask_getenforce(xc_handle); + + xc_interface_close(xc_handle); + + if ( ret < 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return Py_BuildValue("i", ret); +} + +static PyObject *pyflask_setenforce(PyObject *self, PyObject *args, + PyObject *kwds) +{ + xc_interface *xc_handle; + int mode; + int ret; + + static char *kwd_list[] = { "mode", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, + &mode) ) + return NULL; + + xc_handle = xc_interface_open(0,0,0); + if (!xc_handle) { + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_flask_setenforce(xc_handle, mode); + + xc_interface_close(xc_handle); + + if ( ret != 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return Py_BuildValue("i", ret); +} + +static PyObject *pyflask_access(PyObject *self, PyObject *args, + PyObject *kwds) +{ + xc_interface *xc_handle; + char *tcon, *scon; + uint16_t tclass; + uint32_t req, allowed, decided, auditallow, auditdeny, seqno; + int ret; + + static char *kwd_list[] = { "src_context", "tar_context", + "tar_class", "req_permissions", + "decided", "auditallow","auditdeny", + "seqno", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ssil|llll", kwd_list, + &scon, &tcon, &tclass, &req, &decided, + &auditallow, &auditdeny, &seqno) ) + return NULL; + + xc_handle = xc_interface_open(0,0,0); + if (!xc_handle) { + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_flask_access(xc_handle, scon, tcon, tclass, req, &allowed, &decided, + &auditallow, &auditdeny, &seqno); + + xc_interface_close(xc_handle); + + if ( ret != 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return Py_BuildValue("i",ret); +} + static PyMethodDef pyxc_methods[] = { { "domain_create", (PyCFunction)pyxc_domain_create, @@ -2677,6 +2875,59 @@ static PyMethodDef pyxc_methods[] = { "Get info about cpus not in any cpupool.\n" "Returns: [list]: List of CPUs\n" }, + { "flask_context_to_sid", + (PyCFunction)pyflask_context_to_sid, + METH_KEYWORDS, "\n" + "Convert a context string to a dynamic SID.\n" + " context [str]: String specifying context to be converted\n" + "Returns: [int]: Numeric SID on success; -1 on error.\n" }, + + { "flask_sid_to_context", + (PyCFunction)pyflask_sid_to_context, + METH_KEYWORDS, "\n" + "Convert a dynamic SID to context string.\n" + " context [int]: SID to be converted\n" + "Returns: [str]: Numeric SID on success; -1 on error.\n" }, + + { "flask_load", + (PyCFunction)pyflask_load, + METH_KEYWORDS, "\n" + "Loads a policy into the hypervisor.\n" + " policy [str]: policy to be load\n" + "Returns: [int]: 0 on success; -1 on failure.\n" }, + + { "flask_getenforce", + (PyCFunction)pyflask_getenforce, + METH_NOARGS, "\n" + "Returns the current mode of the Flask XSM module.\n" + "Returns: [int]: 0 for permissive; 1 for enforcing; -1 on failure.\n" }, + + { "flask_setenforce", + (PyCFunction)pyflask_setenforce, + METH_KEYWORDS, "\n" + "Modifies the current mode for the Flask XSM module.\n" + " mode [int]: mode to change to\n" + "Returns: [int]: 0 on success; -1 on failure.\n" }, + + { "flask_access", + (PyCFunction)pyflask_access, + METH_KEYWORDS, "\n" + "Returns whether a source context has access to target context based on \ + class and permissions requested.\n" + " scon [str]: source context\n" + " tcon [str]: target context\n" + " tclass [int]: target security class\n" + " req [int] requested permissions\n" + " allowed [int] permissions allow for the target class between the source \ + and target context\n" + " decided [int] the permissions that were returned in the allowed \ + parameter\n" + " auditallow [int] permissions set to audit on allow\n" + " auditdeny [int] permissions set to audit on deny\n" + " seqno [int] not used\n" + "Returns: [int]: 0 on all permission granted; -1 if any permissions are \ + denied\n" }, + { NULL, NULL, 0, NULL } }; |