The FLASK hypercall interface originally attempted to emulate the read/write interface used by SELinux, passing human-readable strings to and from the hypervisor. This resulted in unnecessary string parsing and conversion in the hypervisor and toolstack. This series (primarily patch #3) converts the hypercall to use a union-of-structures similar to the other Xen hypercalls. The wrappers in libxc have been updated to preserve API compatibility where possible. [PATCH 1/4] tools/flask: remove libflask [PATCH 2/4] .gitignore/.hgignore: add missing output files [PATCH 3/4] flask: Update flask_op hypercall structure [PATCH 4/4] xen: Remove unused vsscanf/sscanf functions
This library has been deprecated since July 2010; remove the in-tree users and library. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- tools/flask/Makefile | 1 - tools/flask/libflask/Makefile | 58 ---- tools/flask/libflask/flask_op.c | 559 ------------------------------- tools/flask/libflask/include/libflask.h | 57 ---- tools/flask/utils/Makefile | 15 +- tools/flask/utils/get-bool.c | 9 +- tools/flask/utils/getenforce.c | 3 +- tools/flask/utils/label-pci.c | 17 +- tools/flask/utils/loadpolicy.c | 3 +- tools/flask/utils/set-bool.c | 5 +- tools/flask/utils/setenforce.c | 7 +- tools/libxc/xc_flask.c | 59 ++++ tools/libxc/xenctrl.h | 3 + tools/python/setup.py | 2 +- tools/python/xen/lowlevel/flask/flask.c | 13 +- 15 files changed, 94 insertions(+), 717 deletions(-) delete mode 100644 tools/flask/libflask/Makefile delete mode 100644 tools/flask/libflask/flask_op.c delete mode 100644 tools/flask/libflask/include/libflask.h diff --git a/tools/flask/Makefile b/tools/flask/Makefile index a27b265..add9035 100644 --- a/tools/flask/Makefile +++ b/tools/flask/Makefile @@ -2,7 +2,6 @@ XEN_ROOT = $(CURDIR)/../.. include $(XEN_ROOT)/tools/Rules.mk SUBDIRS :-SUBDIRS += libflask SUBDIRS += utils .PHONY: all clean install diff --git a/tools/flask/libflask/Makefile b/tools/flask/libflask/Makefile deleted file mode 100644 index 12c1c90..0000000 --- a/tools/flask/libflask/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -MAJOR = 1.0 -MINOR = 0 - -XEN_ROOT = $(CURDIR)/../../.. -include $(XEN_ROOT)/tools/Rules.mk - -SRCS :-SRCS += flask_op.c - -CFLAGS += -Werror -CFLAGS += -fno-strict-aliasing -CFLAGS += -I./include $(CFLAGS_libxenctrl) $(CFLAGS_xeninclude) - -LIB_OBJS := $(patsubst %.c,%.o,$(SRCS)) -PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS)) - -LIB := libflask.a -LIB += libflask.so libflask.so.$(MAJOR) libflask.so.$(MAJOR).$(MINOR) - -.PHONY: all -all: build - -.PHONY: build -build: - $(MAKE) $(LIB) - -.PHONY: install -install: build - $(INSTALL_DIR) $(DESTDIR)$(LIBDIR) - $(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR) - $(INSTALL_PROG) libflask.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR) - $(INSTALL_DATA) libflask.a $(DESTDIR)$(LIBDIR) - ln -sf libflask.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)/libflask.so.$(MAJOR) - ln -sf libflask.so.$(MAJOR) $(DESTDIR)$(LIBDIR)/libflask.so - $(INSTALL_DATA) include/libflask.h $(DESTDIR)$(INCLUDEDIR)/xen/xsm - -.PHONY: TAGS -TAGS: - etags -t *.c *.h - -.PHONY: clean -clean: - rm -rf *.a *.so* *.o *.opic *.rpm $(LIB) *~ $(DEPS) xen - -# libflask - -libflask.a: $(LIB_OBJS) - $(AR) rc $@ $^ - -libflask.so: libflask.so.$(MAJOR) - ln -sf $< $@ -libflask.so.$(MAJOR): libflask.so.$(MAJOR).$(MINOR) - ln -sf $< $@ - -libflask.so.$(MAJOR).$(MINOR): $(PIC_OBJS) - $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libflask.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(LDLIBS_libxenctrl) - --include $(DEPS) diff --git a/tools/flask/libflask/flask_op.c b/tools/flask/libflask/flask_op.c deleted file mode 100644 index 412a05d..0000000 --- a/tools/flask/libflask/flask_op.c +++ /dev/null @@ -1,559 +0,0 @@ -/* - * - * Authors: Michael LeMay, <mdlemay@epoch.ncsc.mil> - * George Coker, <gscoker@alpha.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 <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 <libflask.h> - -int 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 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 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 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 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; -} - -int flask_getbool_byid(xc_interface *xc_handle, int id, char *name, int *curr, int *pend) -{ - flask_op_t op; - char buf[255]; - int rv; - - op.cmd = FLASK_GETBOOL2; - op.buf = buf; - op.size = 255; - - snprintf(buf, sizeof buf, "%i", id); - - rv = xc_flask_op(xc_handle, &op); - - if ( rv ) - return rv; - - sscanf(buf, "%i %i %s", curr, pend, name); - - return rv; -} - -int flask_getbool_byname(xc_interface *xc_handle, char *name, int *curr, int *pend) -{ - flask_op_t op; - char buf[255]; - int rv; - - op.cmd = FLASK_GETBOOL_NAMED; - op.buf = buf; - op.size = 255; - - strncpy(buf, name, op.size); - - rv = xc_flask_op(xc_handle, &op); - - if ( rv ) - return rv; - - sscanf(buf, "%i %i", curr, pend); - - return rv; -} - -int flask_setbool(xc_interface *xc_handle, char *name, int value, int commit) -{ - flask_op_t op; - char buf[255]; - int size = 255; - - op.cmd = FLASK_SETBOOL_NAMED; - op.buf = buf; - op.size = size; - - snprintf(buf, size, "%s %i %i", name, value, commit); - - return xc_flask_op(xc_handle, &op); -} - -int flask_add_pirq(xc_interface *xc_handle, unsigned int pirq, char *scontext) -{ - int err; - flask_op_t op; - char *buf; - char *pirq_s = OCON_PIRQ_STR; - int size = INITCONTEXTLEN + strlen(pirq_s) + (sizeof(unsigned int)) + - (sizeof(char) * 3); - - if ( (buf = (char *) malloc(size)) == NULL ) - return -ENOMEM; - memset(buf, 0, size); - - op.cmd = FLASK_ADD_OCONTEXT; - snprintf(buf, size, "%s %255s %u", pirq_s, scontext, pirq); - op.buf = buf; - op.size = size; - - if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) - { - free(buf); - return err; - } - - free(buf); - return 0; - -} - -int flask_add_ioport(xc_interface *xc_handle, unsigned long low, unsigned long high, - char *scontext) -{ - int err; - flask_op_t op; - char *buf; - char *ioport = OCON_IOPORT_STR; - int size = INITCONTEXTLEN + strlen(ioport) + - (sizeof(unsigned long) * 2) + (sizeof(char) * 4); - - if ( (buf = (char *) malloc(size)) == NULL ) - return -ENOMEM; - memset(buf, 0, size); - - op.cmd = FLASK_ADD_OCONTEXT; - snprintf(buf, size, "%s %255s %lu %lu", ioport, scontext, low, high); - op.buf = buf; - op.size = size; - - if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) - { - free(buf); - return err; - } - - free(buf); - return 0; - -} - -int flask_add_iomem(xc_interface *xc_handle, unsigned long low, unsigned long high, - char *scontext) -{ - int err; - flask_op_t op; - char *buf; - char *iomem = OCON_IOMEM_STR; - int size = INITCONTEXTLEN + strlen(iomem) + - (sizeof(unsigned long) * 2) + (sizeof(char) * 4); - - if ( (buf = (char *) malloc(size)) == NULL ) - return -ENOMEM; - memset(buf, 0, size); - - op.cmd = FLASK_ADD_OCONTEXT; - snprintf(buf, size, "%s %255s %lu %lu", iomem, scontext, low, high); - op.buf = buf; - op.size = size; - - if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) - { - free(buf); - return err; - } - - free(buf); - return 0; - -} - -int flask_add_device(xc_interface *xc_handle, unsigned long device, char *scontext) -{ - int err; - flask_op_t op; - char *buf; - char *dev = OCON_DEVICE_STR; - int size = INITCONTEXTLEN + strlen(dev) + (sizeof(unsigned long)) + - (sizeof(char) * 3); - - if ( (buf = (char *) malloc(size)) == NULL ) - return -ENOMEM; - memset(buf, 0, size); - - op.cmd = FLASK_ADD_OCONTEXT; - snprintf(buf, size, "%s %255s %lu", dev, scontext, device); - op.buf = buf; - op.size = size; - - if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) - { - free(buf); - return err; - } - - free(buf); - return 0; - -} - -int flask_del_pirq(xc_interface *xc_handle, unsigned int pirq) -{ - int err; - flask_op_t op; - char *buf; - char *pirq_s = OCON_PIRQ_STR; - int size = strlen(pirq_s) + (sizeof(unsigned int)) + - (sizeof(char) * 2); - - if ( (buf = (char *) malloc(size)) == NULL ) - return -ENOMEM; - memset(buf, 0, size); - - op.cmd = FLASK_DEL_OCONTEXT; - snprintf(buf, size, "%s %u", pirq_s, pirq); - op.buf = buf; - op.size = size; - - if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) - { - free(buf); - return err; - } - - free(buf); - return 0; - -} - -int flask_del_ioport(xc_interface *xc_handle, unsigned long low, unsigned long high) -{ - int err; - flask_op_t op; - char *buf; - char *ioport = OCON_IOPORT_STR; - int size = strlen(ioport) + (sizeof(unsigned long) * 2) + - (sizeof(char) * 3); - - if ( (buf = (char *) malloc(size)) == NULL ) - return -ENOMEM; - memset(buf, 0, size); - - op.cmd = FLASK_DEL_OCONTEXT; - snprintf(buf, size, "%s %lu %lu", ioport, low, high); - op.buf = buf; - op.size = size; - - if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) - { - free(buf); - return err; - } - - free(buf); - return 0; - -} - -int flask_del_iomem(xc_interface *xc_handle, unsigned long low, unsigned long high) -{ - int err; - flask_op_t op; - char *buf; - char *iomem = OCON_IOMEM_STR; - int size = strlen(iomem) + (sizeof(unsigned long) * 2) + - (sizeof(char) * 3); - - if ( (buf = (char *) malloc(size)) == NULL ) - return -ENOMEM; - memset(buf, 0, size); - - op.cmd = FLASK_DEL_OCONTEXT; - snprintf(buf, size, "%s %lu %lu", iomem, low, high); - op.buf = buf; - op.size = size; - - if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) - { - free(buf); - return err; - } - - free(buf); - return 0; - -} - -int flask_del_device(xc_interface *xc_handle, unsigned long device) -{ - int err; - flask_op_t op; - char *buf; - char *dev = OCON_DEVICE_STR; - int size = strlen(dev) + (sizeof(unsigned long)) + (sizeof(char) * 2); - - if ( (buf = (char *) malloc(size)) == NULL ) - return -ENOMEM; - memset(buf, 0, size); - - op.cmd = FLASK_DEL_OCONTEXT; - snprintf(buf, size, "%s %lu", dev, device); - op.buf = buf; - op.size = size; - - if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) - { - free(buf); - return err; - } - - free(buf); - return 0; - -} - -int flask_access(xc_interface *xc_handle, const char *scon, const char *tcon, - u_int16_t tclass, u_int32_t req, - u_int32_t *allowed, u_int32_t *decided, - u_int32_t *auditallow, u_int32_t *auditdeny, - u_int32_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; - u_int32_t dummy_allowed; - u_int32_t dummy_decided; - u_int32_t dummy_auditallow; - u_int32_t dummy_auditdeny; - u_int32_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 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 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 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 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 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; -} diff --git a/tools/flask/libflask/include/libflask.h b/tools/flask/libflask/include/libflask.h deleted file mode 100644 index b8a6ca9..0000000 --- a/tools/flask/libflask/include/libflask.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * Authors: Michael LeMay, <mdlemay@epoch.ncsc.mil> - * George Coker, <gscoker@alpha.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. - */ - -#ifndef __LIBFLASK_H__ -#define __LIBFLASK_H__ - -#include <stdint.h> -#include <xen/xen.h> -#include <xen/xsm/flask_op.h> -#include <xenctrl.h> - -int flask_load(xc_interface *xc_handle, char *buf, uint32_t size); -int flask_context_to_sid(xc_interface *xc_handle, char *buf, uint32_t size, uint32_t *sid); -int flask_sid_to_context(xc_interface *xc_handle, int sid, char *buf, uint32_t size); -int flask_getenforce(xc_interface *xc_handle); -int flask_setenforce(xc_interface *xc_handle, int mode); -int flask_getbool_byid(xc_interface *xc_handle, int id, char *name, int *curr, int *pend); -int flask_getbool_byname(xc_interface *xc_handle, char *name, int *curr, int *pend); -int flask_setbool(xc_interface *xc_handle, char *name, int value, int commit); -int flask_add_pirq(xc_interface *xc_handle, unsigned int pirq, char *scontext); -int flask_add_ioport(xc_interface *xc_handle, unsigned long low, unsigned long high, - char *scontext); -int flask_add_iomem(xc_interface *xc_handle, unsigned long low, unsigned long high, - char *scontext); -int flask_add_device(xc_interface *xc_handle, unsigned long device, char *scontext); -int flask_del_pirq(xc_interface *xc_handle, unsigned int pirq); -int flask_del_ioport(xc_interface *xc_handle, unsigned long low, unsigned long high); -int flask_del_iomem(xc_interface *xc_handle, unsigned long low, unsigned long high); -int flask_del_device(xc_interface *xc_handle, unsigned long device); -int flask_access(xc_interface *xc_handle, const char *scon, const char *tcon, - u_int16_t tclass, u_int32_t req, - u_int32_t *allowed, u_int32_t *decided, - u_int32_t *auditallow, u_int32_t *auditdeny, - u_int32_t *seqno); -int flask_avc_cachestats(xc_interface *xc_handle, char *buf, int size); -int flask_policyvers(xc_interface *xc_handle, char *buf, int size); -int flask_avc_hashstats(xc_interface *xc_handle, char *buf, int size); -int flask_getavc_threshold(xc_interface *xc_handle); -int flask_setavc_threshold(xc_interface *xc_handle, int threshold); -#define flask_add_single_ioport(x, l, s) flask_add_ioport(x, l, l, s) -#define flask_add_single_iomem(x, l, s) flask_add_iomem(x, l, l, s) -#define flask_del_single_ioport(x, l) flask_del_ioport(x, l, l) -#define flask_del_single_iomem(x, l) flask_del_iomem(x, l, l); - -#define OCON_PIRQ_STR "pirq" -#define OCON_IOPORT_STR "ioport" -#define OCON_IOMEM_STR "iomem" -#define OCON_DEVICE_STR "pcidevice" -#define INITCONTEXTLEN 256 -#endif /* __LIBFLASK_H__ */ diff --git a/tools/flask/utils/Makefile b/tools/flask/utils/Makefile index 3ac6ac2..458f9aa 100644 --- a/tools/flask/utils/Makefile +++ b/tools/flask/utils/Makefile @@ -1,11 +1,8 @@ XEN_ROOT=$(CURDIR)/../../.. include $(XEN_ROOT)/tools/Rules.mk -LIBFLASK_ROOT = $(XEN_ROOT)/tools/flask/libflask - CFLAGS += -Wall -g -Werror CFLAGS += $(CFLAGS_libxenctrl) -CFLAGS += -I$(LIBFLASK_ROOT)/include TESTDIR = testsuite/tmp TESTFLAGS= -DTESTING @@ -19,22 +16,22 @@ CLIENTS_OBJS := $(patsubst flask-%,%.o,$(CLIENTS)) all: $(CLIENTS) flask-loadpolicy: loadpolicy.o - $(CC) $(LDFLAGS) $< $(LDLIBS) -L$(LIBFLASK_ROOT) -lflask $(LDLIBS_libxenctrl) -o $@ + $(CC) $(LDFLAGS) $< $(LDLIBS) $(LDLIBS_libxenctrl) -o $@ flask-setenforce: setenforce.o - $(CC) $(LDFLAGS) $< $(LDLIBS) -L$(LIBFLASK_ROOT) -lflask $(LDLIBS_libxenctrl) -o $@ + $(CC) $(LDFLAGS) $< $(LDLIBS) $(LDLIBS_libxenctrl) -o $@ flask-getenforce: getenforce.o - $(CC) $(LDFLAGS) $< $(LDLIBS) -L$(LIBFLASK_ROOT) -lflask $(LDLIBS_libxenctrl) -o $@ + $(CC) $(LDFLAGS) $< $(LDLIBS) $(LDLIBS_libxenctrl) -o $@ flask-label-pci: label-pci.o - $(CC) $(LDFLAGS) $< $(LDLIBS) -L$(LIBFLASK_ROOT) -lflask $(LDLIBS_libxenctrl) -o $@ + $(CC) $(LDFLAGS) $< $(LDLIBS) $(LDLIBS_libxenctrl) -o $@ flask-get-bool: get-bool.o - $(CC) $(LDFLAGS) $< $(LDLIBS) -L$(LIBFLASK_ROOT) -lflask $(LDLIBS_libxenctrl) -o $@ + $(CC) $(LDFLAGS) $< $(LDLIBS) $(LDLIBS_libxenctrl) -o $@ flask-set-bool: set-bool.o - $(CC) $(LDFLAGS) $< $(LDLIBS) -L$(LIBFLASK_ROOT) -lflask $(LDLIBS_libxenctrl) -o $@ + $(CC) $(LDFLAGS) $< $(LDLIBS) $(LDLIBS_libxenctrl) -o $@ .PHONY: clean clean: diff --git a/tools/flask/utils/get-bool.c b/tools/flask/utils/get-bool.c index c0cd7c8..7833522 100644 --- a/tools/flask/utils/get-bool.c +++ b/tools/flask/utils/get-bool.c @@ -16,7 +16,6 @@ #include <string.h> #include <unistd.h> #include <inttypes.h> -#include <libflask.h> static void usage(char **argv) { @@ -29,11 +28,11 @@ static int all_bools(xc_interface *xch) int err = 0, i = 0, curr, pend; char name[256]; while (1) { - err = flask_getbool_byid(xch, i, name, &curr, &pend); + err = xc_flask_getbool_byid(xch, i, name, sizeof name, &curr, &pend); if (err < 0) { if (errno == ENOENT) return 0; - fprintf(stderr, "flask_getbool: Unable to get boolean #%d: %s (%d)", + fprintf(stderr, "xc_flask_getbool: Unable to get boolean #%d: %s (%d)", i, strerror(errno), err); return 2; } @@ -69,9 +68,9 @@ int main(int argc, char **argv) goto done; } - err = flask_getbool_byname(xch, argv[1], &curr, &pend); + err = xc_flask_getbool_byname(xch, argv[1], &curr, &pend); if (err) { - fprintf(stderr, "flask_getbool: Unable to get boolean %s: %s (%d)", + fprintf(stderr, "xc_flask_getbool: Unable to get boolean %s: %s (%d)", argv[1], strerror(errno), err); err = 2; goto done; diff --git a/tools/flask/utils/getenforce.c b/tools/flask/utils/getenforce.c index 281fc81..fedf336 100644 --- a/tools/flask/utils/getenforce.c +++ b/tools/flask/utils/getenforce.c @@ -16,7 +16,6 @@ #include <sys/stat.h> #include <string.h> #include <unistd.h> -#include <libflask.h> static void usage (int argCnt, const char *args[]) { @@ -41,7 +40,7 @@ int main (int argCnt, const char *args[]) goto done; } - ret = flask_getenforce(xch); + ret = xc_flask_getenforce(xch); if ( ret < 0 ) { errno = -ret; diff --git a/tools/flask/utils/label-pci.c b/tools/flask/utils/label-pci.c index da0cb61..9ddb713 100644 --- a/tools/flask/utils/label-pci.c +++ b/tools/flask/utils/label-pci.c @@ -16,7 +16,6 @@ #include <string.h> #include <unistd.h> #include <inttypes.h> -#include <libflask.h> /* Pulled from linux/include/linux/ioport.h */ #define IORESOURCE_TYPE_BITS 0x00001f00 /* Resource type */ @@ -69,9 +68,9 @@ int main (int argCnt, char *argv[]) goto done; } - ret = flask_add_device(xch, sbdf, argv[2]); + ret = xc_flask_add_device(xch, sbdf, argv[2]); if (ret) { - fprintf(stderr, "flask_add_device: Unable to set context of PCI device %s (0x%x) to %s: %d\n", + fprintf(stderr, "xc_flask_add_device: Unable to set context of PCI device %s (0x%x) to %s: %d\n", argv[1], sbdf, argv[2], ret); err = 2; goto done; @@ -80,9 +79,9 @@ int main (int argCnt, char *argv[]) while (fscanf(f, "0x%"SCNx64" 0x%"SCNx64" 0x%"SCNx64"\n", &start, &end, &flags) == 3) { if (flags & IORESOURCE_IO) { // printf("Port %"PRIx64"-%"PRIx64"\n", start, end); - ret = flask_add_ioport(xch, start, end, argv[2]); + ret = xc_flask_add_ioport(xch, start, end, argv[2]); if (ret) { - fprintf(stderr, "flask_add_ioport %"PRIx64"-%"PRIx64" failed: %d\n", + fprintf(stderr, "xc_flask_add_ioport %"PRIx64"-%"PRIx64" failed: %d\n", start, end, ret); err = 2; } @@ -90,9 +89,9 @@ int main (int argCnt, char *argv[]) start >>= 12; end >>= 12; // printf("IOMEM %"PRIx64"-%"PRIx64"\n", start, end); - ret = flask_add_iomem(xch, start, end, argv[2]); + ret = xc_flask_add_iomem(xch, start, end, argv[2]); if (ret) { - fprintf(stderr, "flask_add_iomem %"PRIx64"-%"PRIx64" failed: %d\n", + fprintf(stderr, "xc_flask_add_iomem %"PRIx64"-%"PRIx64" failed: %d\n", start, end, ret); err = 2; } @@ -108,9 +107,9 @@ int main (int argCnt, char *argv[]) if (fscanf(f, "%" SCNu64, &start) != 1) start = 0; if (start) { - ret = flask_add_pirq(xch, start, argv[2]); + ret = xc_flask_add_pirq(xch, start, argv[2]); if (ret) { - fprintf(stderr, "flask_add_pirq %"PRIu64" failed: %d\n", + fprintf(stderr, "xc_flask_add_pirq %"PRIu64" failed: %d\n", start, ret); err = 2; } diff --git a/tools/flask/utils/loadpolicy.c b/tools/flask/utils/loadpolicy.c index 4e99c71..f347b97 100644 --- a/tools/flask/utils/loadpolicy.c +++ b/tools/flask/utils/loadpolicy.c @@ -17,7 +17,6 @@ #include <sys/stat.h> #include <string.h> #include <unistd.h> -#include <libflask.h> #define USE_MMAP @@ -94,7 +93,7 @@ int main (int argCnt, const char *args[]) } #endif - ret = flask_load(xch, polMemCp, info.st_size); + ret = xc_flask_load(xch, polMemCp, info.st_size); if ( ret < 0 ) { errno = -ret; diff --git a/tools/flask/utils/set-bool.c b/tools/flask/utils/set-bool.c index cde25cd..4b847c5 100644 --- a/tools/flask/utils/set-bool.c +++ b/tools/flask/utils/set-bool.c @@ -16,7 +16,6 @@ #include <string.h> #include <unistd.h> #include <inttypes.h> -#include <libflask.h> static void usage(char **argv) { @@ -56,9 +55,9 @@ int main(int argc, char **argv) goto done; } - err = flask_setbool(xch, argv[1], value, 1); + err = xc_flask_setbool(xch, argv[1], value, 1); if (err) { - fprintf(stderr, "flask_setbool: Unable to set boolean %s=%s: %s (%d)", + fprintf(stderr, "xc_flask_setbool: Unable to set boolean %s=%s: %s (%d)", argv[1], argv[2], strerror(errno), err); err = 2; goto done; diff --git a/tools/flask/utils/setenforce.c b/tools/flask/utils/setenforce.c index 63928bd..0a92d53 100644 --- a/tools/flask/utils/setenforce.c +++ b/tools/flask/utils/setenforce.c @@ -16,7 +16,6 @@ #include <sys/stat.h> #include <string.h> #include <unistd.h> -#include <libflask.h> static void usage (int argCnt, const char *args[]) { @@ -45,12 +44,12 @@ int main (int argCnt, const char *args[]) if( strlen(args[1]) == 1 && (args[1][0] == ''0'' || args[1][0] == ''1'')){ mode = strtol(args[1], &end, 10); - ret = flask_setenforce(xch, mode); + ret = xc_flask_setenforce(xch, mode); } else { if( strcasecmp(args[1], "enforcing") == 0 ){ - ret = flask_setenforce(xch, 1); + ret = xc_flask_setenforce(xch, 1); } else if( strcasecmp(args[1], "permissive") == 0 ){ - ret = flask_setenforce(xch, 0); + ret = xc_flask_setenforce(xch, 0); } else { usage(argCnt, args); } diff --git a/tools/libxc/xc_flask.c b/tools/libxc/xc_flask.c index 27794a8..d268098 100644 --- a/tools/libxc/xc_flask.c +++ b/tools/libxc/xc_flask.c @@ -151,6 +151,65 @@ int xc_flask_setenforce(xc_interface *xc_handle, int mode) return 0; } +int xc_flask_getbool_byid(xc_interface *xc_handle, int id, char *name, uint32_t size, int *curr, int *pend) +{ + flask_op_t op; + char buf[255]; + int rv; + + op.cmd = FLASK_GETBOOL2; + op.buf = buf; + op.size = 255; + + snprintf(buf, sizeof buf, "%i", id); + + rv = xc_flask_op(xc_handle, &op); + + if ( rv ) + return rv; + + sscanf(buf, "%i %i %s", curr, pend, name); + + return rv; +} + +int xc_flask_getbool_byname(xc_interface *xc_handle, char *name, int *curr, int *pend) +{ + flask_op_t op; + char buf[255]; + int rv; + + op.cmd = FLASK_GETBOOL_NAMED; + op.buf = buf; + op.size = 255; + + strncpy(buf, name, op.size); + + rv = xc_flask_op(xc_handle, &op); + + if ( rv ) + return rv; + + sscanf(buf, "%i %i", curr, pend); + + return rv; +} + +int xc_flask_setbool(xc_interface *xc_handle, char *name, int value, int commit) +{ + flask_op_t op; + char buf[255]; + int size = 255; + + op.cmd = FLASK_SETBOOL_NAMED; + op.buf = buf; + op.size = size; + + snprintf(buf, size, "%s %i %i", name, value, commit); + + return xc_flask_op(xc_handle, &op); +} + static int xc_flask_add(xc_interface *xc_handle, char *cat, char *arg, char *scontext) { char buf[512]; diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index f0edde6..1e7c32b 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -1957,6 +1957,9 @@ int xc_flask_context_to_sid(xc_interface *xc_handle, char *buf, uint32_t size, u 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_getbool_byid(xc_interface *xc_handle, int id, char *name, uint32_t size, int *curr, int *pend); +int xc_flask_getbool_byname(xc_interface *xc_handle, char *name, int *curr, int *pend); +int xc_flask_setbool(xc_interface *xc_handle, char *name, int value, int commit); 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); diff --git a/tools/python/setup.py b/tools/python/setup.py index 81540bc..e9061c8 100644 --- a/tools/python/setup.py +++ b/tools/python/setup.py @@ -48,7 +48,7 @@ flask = Extension("flask", include_dirs = [ PATH_XEN, PATH_LIBXC, "xen/lowlevel/flask", "../flask/libflask/include" ], library_dirs = [ PATH_LIBXC, "../flask/libflask" ], - libraries = [ "xenctrl", "flask" ], + libraries = [ "xenctrl" ], depends = [ PATH_LIBXC + "/libxenctrl.so", XEN_ROOT + "/tools/flask/libflask/libflask.so" ], sources = [ "xen/lowlevel/flask/flask.c" ]) diff --git a/tools/python/xen/lowlevel/flask/flask.c b/tools/python/xen/lowlevel/flask/flask.c index 64e8d63..c3fcf3b 100644 --- a/tools/python/xen/lowlevel/flask/flask.c +++ b/tools/python/xen/lowlevel/flask/flask.c @@ -12,7 +12,6 @@ #include <Python.h> #include <xenctrl.h> -#include <libflask.h> #define PKG "xen.lowlevel.flask" #define CLS "flask" @@ -58,7 +57,7 @@ static PyObject *pyflask_context_to_sid(PyObject *self, PyObject *args, return PyErr_SetFromErrno(xc_error_obj); } - ret = flask_context_to_sid(xc_handle, buf, len, &sid); + ret = xc_flask_context_to_sid(xc_handle, buf, len, &sid); xc_interface_close(xc_handle); @@ -92,7 +91,7 @@ static PyObject *pyflask_sid_to_context(PyObject *self, PyObject *args, return PyErr_SetFromErrno(xc_error_obj); } - ret = flask_sid_to_context(xc_handle, sid, ctx, ctx_len); + ret = xc_flask_sid_to_context(xc_handle, sid, ctx, ctx_len); xc_interface_close(xc_handle); @@ -121,7 +120,7 @@ static PyObject *pyflask_load(PyObject *self, PyObject *args, PyObject *kwds) return PyErr_SetFromErrno(xc_error_obj); } - ret = flask_load(xc_handle, policy, len); + ret = xc_flask_load(xc_handle, policy, len); xc_interface_close(xc_handle); @@ -143,7 +142,7 @@ static PyObject *pyflask_getenforce(PyObject *self) return PyErr_SetFromErrno(xc_error_obj); } - ret = flask_getenforce(xc_handle); + ret = xc_flask_getenforce(xc_handle); xc_interface_close(xc_handle); @@ -173,7 +172,7 @@ static PyObject *pyflask_setenforce(PyObject *self, PyObject *args, return PyErr_SetFromErrno(xc_error_obj); } - ret = flask_setenforce(xc_handle, mode); + ret = xc_flask_setenforce(xc_handle, mode); xc_interface_close(xc_handle); @@ -209,7 +208,7 @@ static PyObject *pyflask_access(PyObject *self, PyObject *args, return PyErr_SetFromErrno(xc_error_obj); } - ret = flask_access(xc_handle, scon, tcon, tclass, req, &allowed, &decided, + ret = xc_flask_access(xc_handle, scon, tcon, tclass, req, &allowed, &decided, &auditallow, &auditdeny, &seqno); xc_interface_close(xc_handle); -- 1.7.7.6
Daniel De Graaf
2012-Feb-03 15:12 UTC
[PATCH 2/4] .gitignore/.hgignore: add missing output files
- extras/mini-os/include/list.h (already in .hgignore) - tools/flask/flask-{get,set}-bool - tools/flask/loadpolicy no longer exists - tools/xenstore/init-xenstore-domain Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- .gitignore | 5 ++++- .hgignore | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 13d3e94..d1c4e46 100644 --- a/.gitignore +++ b/.gitignore @@ -64,6 +64,7 @@ extras/mini-os/include/ia64/mini-os extras/mini-os/include/ia64/offsets.h extras/mini-os/include/x86/mini-os extras/mini-os/include/xen +extras/mini-os/include/list.h extras/mini-os/mini-os* install/* linux-[^/]*-paravirt/* @@ -150,10 +151,11 @@ tools/firmware/rombios/rombios[^/]*.s tools/firmware/rombios/32bit/32bitbios_flat.h tools/firmware/vgabios/vbetables-gen tools/firmware/vgabios/vbetables.h -tools/flask/loadpolicy/flask-loadpolicy tools/flask/utils/flask-getenforce +tools/flask/utils/flask-get-bool tools/flask/utils/flask-loadpolicy tools/flask/utils/flask-setenforce +tools/flask/utils/flask-set-bool tools/flask/utils/flask-label-pci tools/fs-back/fs-backend tools/hotplug/common/hotplugpath.sh @@ -236,6 +238,7 @@ tools/xenpaging/xenpaging tools/xenpmd/xenpmd tools/xenstat/xentop/xentop tools/xenstore/testsuite/tmp/* +tools/xenstore/init-xenstore-domain tools/xenstore/xen tools/xenstore/xenstore tools/xenstore/xenstore-chmod diff --git a/.hgignore b/.hgignore index 2b5cfe5..f474c42 100644 --- a/.hgignore +++ b/.hgignore @@ -154,10 +154,11 @@ ^tools/firmware/rombios/32bit/32bitbios_flat\.h$ ^tools/firmware/vgabios/vbetables-gen$ ^tools/firmware/vgabios/vbetables\.h$ -^tools/flask/loadpolicy/flask-loadpolicy$ ^tools/flask/utils/flask-getenforce$ +^tools/flask/utils/flask-get-bool$ ^tools/flask/utils/flask-loadpolicy$ ^tools/flask/utils/flask-setenforce$ +^tools/flask/utils/flask-set-bool$ ^tools/flask/utils/flask-label-pci$ ^tools/fs-back/fs-backend$ ^tools/hotplug/common/hotplugpath\.sh$ @@ -249,6 +250,7 @@ ^tools/xenpmd/xenpmd$ ^tools/xenstat/xentop/xentop$ ^tools/xenstore/testsuite/tmp/.*$ +^tools/xenstore/init-xenstore-domain$ ^tools/xenstore/xen$ ^tools/xenstore/xenstore$ ^tools/xenstore/xenstore-chmod$ -- 1.7.7.6
Daniel De Graaf
2012-Feb-03 15:13 UTC
[PATCH 3/4] flask: Update flask_op hypercall structure
Instead of placing string parsing inside the hypervisor, use binary structures like other Xen hypercalls do. This patch also removes libflask; if the old flask_* namespace is needed for longer backwards compatability (it was noted as deprecated in July 2010), a shim redirecting to the proper xc_flask_* calls can be created. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- tools/libxc/xc_flask.c | 471 +++++++--------- tools/libxc/xc_private.h | 2 + tools/libxc/xenctrl.h | 4 +- xen/include/public/xsm/flask_op.h | 146 +++++- xen/xsm/flask/avc.c | 13 +- xen/xsm/flask/flask_op.c | 1128 +++++++++++-------------------------- xen/xsm/flask/include/avc.h | 3 +- xen/xsm/flask/include/security.h | 4 +- xen/xsm/flask/ss/services.c | 11 +- 9 files changed, 683 insertions(+), 1099 deletions(-) diff --git a/tools/libxc/xc_flask.c b/tools/libxc/xc_flask.c index d268098..80c5a2d 100644 --- a/tools/libxc/xc_flask.c +++ b/tools/libxc/xc_flask.c @@ -30,18 +30,21 @@ #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 OCON_ISID 0 /* initial SIDs */ +#define OCON_PIRQ 1 /* physical irqs */ +#define OCON_IOPORT 2 /* io ports */ +#define OCON_IOMEM 3 /* io memory */ +#define OCON_DEVICE 4 /* pci devices */ #define INITCONTEXTLEN 256 -int xc_flask_op(xc_interface *xch, flask_op_t *op) +int xc_flask_op(xc_interface *xch, xen_flask_op_t *op) { int ret = -1; DECLARE_HYPERCALL; DECLARE_HYPERCALL_BOUNCE(op, sizeof(*op), XC_HYPERCALL_BUFFER_BOUNCE_BOTH); + op->interface_version = XEN_FLASK_INTERFACE_VERSION; + if ( xc_hypercall_bounce_pre(xch, op) ) { PERROR("Could not bounce memory for flask op hypercall"); @@ -63,402 +66,360 @@ 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 xc_flask_load(xc_interface *xch, char *buf, uint32_t size) { int err; - flask_op_t op; - + DECLARE_FLASK_OP; + DECLARE_HYPERCALL_BOUNCE(buf, size, XC_HYPERCALL_BUFFER_BOUNCE_IN); + if ( xc_hypercall_bounce_pre(xch, buf) ) + { + PERROR("Could not bounce memory for flask op hypercall"); + return -1; + } + op.cmd = FLASK_LOAD; - op.buf = buf; - op.size = size; + op.u.load.size = size; + set_xen_guest_handle(op.u.load.buffer, buf); - if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) - return err; + err = xc_flask_op(xch, &op); - return 0; + xc_hypercall_bounce_post(xch, buf); + + return err; } -int xc_flask_context_to_sid(xc_interface *xc_handle, char *buf, uint32_t size, uint32_t *sid) +int xc_flask_context_to_sid(xc_interface *xch, char *buf, uint32_t size, uint32_t *sid) { int err; - flask_op_t op; - + DECLARE_FLASK_OP; + DECLARE_HYPERCALL_BOUNCE(buf, size, XC_HYPERCALL_BUFFER_BOUNCE_IN); + + if ( xc_hypercall_bounce_pre(xch, buf) ) + { + PERROR("Could not bounce memory for flask op hypercall"); + return -1; + } + op.cmd = FLASK_CONTEXT_TO_SID; - op.buf = buf; - op.size = size; + op.u.sid_context.size = size; + set_xen_guest_handle(op.u.sid_context.context, buf); - if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) - return err; - - sscanf(buf, "%u", sid); + err = xc_flask_op(xch, &op); - return 0; + if ( !err ) + *sid = op.u.sid_context.sid; + + xc_hypercall_bounce_post(xch, buf); + + return err; } -int xc_flask_sid_to_context(xc_interface *xc_handle, int sid, char *buf, uint32_t size) +int xc_flask_sid_to_context(xc_interface *xch, int sid, char *buf, uint32_t size) { int err; - flask_op_t op; - + DECLARE_FLASK_OP; + DECLARE_HYPERCALL_BOUNCE(buf, size, XC_HYPERCALL_BUFFER_BOUNCE_OUT); + + if ( xc_hypercall_bounce_pre(xch, buf) ) + { + PERROR("Could not bounce memory for flask op hypercall"); + return -1; + } + op.cmd = FLASK_SID_TO_CONTEXT; - op.buf = buf; - op.size = size; + op.u.sid_context.sid = sid; + op.u.sid_context.size = size; + set_xen_guest_handle(op.u.sid_context.context, buf); - snprintf(buf, size, "%u", sid); + err = xc_flask_op(xch, &op); - if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) - return err; - - return 0; + xc_hypercall_bounce_post(xch, buf); + + return err; } -int xc_flask_getenforce(xc_interface *xc_handle) +int xc_flask_getenforce(xc_interface *xch) { - int err; - flask_op_t op; - char buf[20]; - int size = 20; - int mode; - + DECLARE_FLASK_OP; 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; + return xc_flask_op(xch, &op); } -int xc_flask_setenforce(xc_interface *xc_handle, int mode) +int xc_flask_setenforce(xc_interface *xch, int mode) { - int err; - flask_op_t op; - char buf[20]; - int size = 20; - + DECLARE_FLASK_OP; op.cmd = FLASK_SETENFORCE; - op.buf = buf; - op.size = size; + op.u.enforce.enforcing = mode; - snprintf(buf, size, "%i", mode); - - if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) - return err; - - return 0; + return xc_flask_op(xch, &op); } -int xc_flask_getbool_byid(xc_interface *xc_handle, int id, char *name, uint32_t size, int *curr, int *pend) +int xc_flask_getbool_byid(xc_interface *xch, int id, char *name, uint32_t size, int *curr, int *pend) { - flask_op_t op; - char buf[255]; int rv; + DECLARE_FLASK_OP; + DECLARE_HYPERCALL_BOUNCE(name, size, XC_HYPERCALL_BUFFER_BOUNCE_OUT); + + if ( xc_hypercall_bounce_pre(xch, name) ) + { + PERROR("Could not bounce memory for flask op hypercall"); + return -1; + } - op.cmd = FLASK_GETBOOL2; - op.buf = buf; - op.size = 255; + op.cmd = FLASK_GETBOOL; + op.u.boolean.bool_id = id; + op.u.boolean.size = size; + set_xen_guest_handle(op.u.boolean.name, name); - snprintf(buf, sizeof buf, "%i", id); + rv = xc_flask_op(xch, &op); - rv = xc_flask_op(xc_handle, &op); + xc_hypercall_bounce_post(xch, name); if ( rv ) return rv; - sscanf(buf, "%i %i %s", curr, pend, name); + if ( curr ) + *curr = op.u.boolean.enforcing; + if ( pend ) + *pend = op.u.boolean.pending; return rv; } -int xc_flask_getbool_byname(xc_interface *xc_handle, char *name, int *curr, int *pend) +int xc_flask_getbool_byname(xc_interface *xch, char *name, int *curr, int *pend) { - flask_op_t op; - char buf[255]; int rv; + DECLARE_FLASK_OP; + DECLARE_HYPERCALL_BOUNCE(name, strlen(name), XC_HYPERCALL_BUFFER_BOUNCE_IN); - op.cmd = FLASK_GETBOOL_NAMED; - op.buf = buf; - op.size = 255; + op.cmd = FLASK_GETBOOL; + op.u.boolean.bool_id = -1; + op.u.boolean.size = strlen(name); + set_xen_guest_handle(op.u.boolean.name, name); - strncpy(buf, name, op.size); + rv = xc_flask_op(xch, &op); - rv = xc_flask_op(xc_handle, &op); + xc_hypercall_bounce_post(xch, name); if ( rv ) return rv; - sscanf(buf, "%i %i", curr, pend); + if ( curr ) + *curr = op.u.boolean.enforcing; + if ( pend ) + *pend = op.u.boolean.pending; return rv; } -int xc_flask_setbool(xc_interface *xc_handle, char *name, int value, int commit) +int xc_flask_setbool(xc_interface *xch, char *name, int value, int commit) { - flask_op_t op; - char buf[255]; - int size = 255; + int rv; + DECLARE_FLASK_OP; + DECLARE_HYPERCALL_BOUNCE(name, strlen(name), XC_HYPERCALL_BUFFER_BOUNCE_IN); - op.cmd = FLASK_SETBOOL_NAMED; - op.buf = buf; - op.size = size; + op.cmd = FLASK_SETBOOL; + op.u.boolean.bool_id = -1; + op.u.boolean.new_value = value; + op.u.boolean.commit = 1; + op.u.boolean.size = strlen(name); + set_xen_guest_handle(op.u.boolean.name, name); - snprintf(buf, size, "%s %i %i", name, value, commit); + rv = xc_flask_op(xch, &op); - return xc_flask_op(xc_handle, &op); + xc_hypercall_bounce_post(xch, name); + + return rv; } -static int xc_flask_add(xc_interface *xc_handle, char *cat, char *arg, char *scontext) + +static int xc_flask_add(xc_interface *xch, uint32_t ocon, uint64_t low, uint64_t high, char *scontext) { - char buf[512]; - flask_op_t op; + uint32_t sid; + int err; + DECLARE_FLASK_OP; + + err = xc_flask_context_to_sid(xch, scontext, strlen(scontext), &sid); + if ( err ) + return err; - memset(buf, 0, 512); - snprintf(buf, 512, "%s %255s %s", cat, scontext, arg); op.cmd = FLASK_ADD_OCONTEXT; - op.buf = buf; - op.size = 512; + op.u.ocontext.ocon = ocon; + op.u.ocontext.sid = sid; + op.u.ocontext.low = low; + op.u.ocontext.high = high; - return xc_flask_op(xc_handle, &op); + return xc_flask_op(xch, &op); } -int xc_flask_add_pirq(xc_interface *xc_handle, unsigned int pirq, char *scontext) +int xc_flask_add_pirq(xc_interface *xch, unsigned int pirq, char *scontext) { - char arg[16]; - - snprintf(arg, 16, "%u", pirq); - return xc_flask_add(xc_handle, OCON_PIRQ_STR, arg, scontext); + return xc_flask_add(xch, OCON_PIRQ, pirq, pirq, scontext); } -int xc_flask_add_ioport(xc_interface *xc_handle, unsigned long low, unsigned long high, +int xc_flask_add_ioport(xc_interface *xch, 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); + return xc_flask_add(xch, OCON_IOPORT, low, high, scontext); } -int xc_flask_add_iomem(xc_interface *xc_handle, unsigned long low, unsigned long high, +int xc_flask_add_iomem(xc_interface *xch, 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); + return xc_flask_add(xch, OCON_IOMEM, low, high, scontext); } -int xc_flask_add_device(xc_interface *xc_handle, unsigned long device, char *scontext) +int xc_flask_add_device(xc_interface *xch, unsigned long device, char *scontext) { - char arg[32]; - - snprintf(arg, 32, "%lu", device); - return xc_flask_add(xc_handle, OCON_DEVICE_STR, arg, scontext); + return xc_flask_add(xch, OCON_DEVICE, device, device, scontext); } -static int xc_flask_del(xc_interface *xc_handle, char *cat, char *arg) +static int xc_flask_del(xc_interface *xch, uint32_t ocon, uint64_t low, uint64_t high) { - char buf[256]; - flask_op_t op; + DECLARE_FLASK_OP; - memset(buf, 0, 256); - snprintf(buf, 256, "%s %s", cat, arg); op.cmd = FLASK_DEL_OCONTEXT; - op.buf = buf; - op.size = 256; + op.u.ocontext.ocon = ocon; + op.u.ocontext.low = low; + op.u.ocontext.high = high; - return xc_flask_op(xc_handle, &op); + return xc_flask_op(xch, &op); } -int xc_flask_del_pirq(xc_interface *xc_handle, unsigned int pirq) +int xc_flask_del_pirq(xc_interface *xch, unsigned int pirq) { - char arg[16]; - - snprintf(arg, 16, "%u", pirq); - return xc_flask_del(xc_handle, OCON_PIRQ_STR, arg); + return xc_flask_del(xch, OCON_PIRQ, pirq, pirq); } -int xc_flask_del_ioport(xc_interface *xc_handle, unsigned long low, unsigned long high) +int xc_flask_del_ioport(xc_interface *xch, 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); + return xc_flask_del(xch, OCON_IOPORT, low, high); } -int xc_flask_del_iomem(xc_interface *xc_handle, unsigned long low, unsigned long high) +int xc_flask_del_iomem(xc_interface *xch, 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); + return xc_flask_del(xch, OCON_IOMEM, low, high); } -int xc_flask_del_device(xc_interface *xc_handle, unsigned long device) +int xc_flask_del_device(xc_interface *xch, unsigned long device) { - char arg[32]; - - snprintf(arg, 32, "%lu", device); - return xc_flask_del(xc_handle, OCON_DEVICE_STR, arg); + return xc_flask_del(xch, OCON_DEVICE, device, device); } -int xc_flask_access(xc_interface *xc_handle, const char *scon, const char *tcon, +int xc_flask_access(xc_interface *xch, 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; + DECLARE_FLASK_OP; 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); + + err = xc_flask_context_to_sid(xch, (char*)scon, strlen(scon), &op.u.access.ssid); + if ( err ) + return err; + err = xc_flask_context_to_sid(xch, (char*)tcon, strlen(tcon), &op.u.access.tsid); + if ( err ) + return err; op.cmd = FLASK_ACCESS; - op.buf = buf; - op.size = strlen(buf)+1; + op.u.access.tclass = tclass; + op.u.access.req = req; - if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) - { - free(buf); + err = xc_flask_op(xch, &op); + + if ( err ) 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; + if ( allowed ) + *allowed = op.u.access.allowed; + if ( decided ) + *decided = 0xffffffff; + if ( auditallow ) + *auditallow = op.u.access.audit_allow; + if ( auditdeny ) + *auditdeny = op.u.access.audit_deny; + if ( seqno ) + *seqno = op.u.access.seqno; - return err; + if ( (op.u.access.allowed & req) != req ) + err = -EPERM; + return err; } -int xc_flask_avc_hashstats(xc_interface *xc_handle, char *buf, int size) +int xc_flask_avc_hashstats(xc_interface *xch, char *buf, int size) { int err; - flask_op_t op; + DECLARE_FLASK_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; - } + err = xc_flask_op(xch, &op); - return 0; + snprintf(buf, size, + "entries: %d\nbuckets used: %d/%d\nlongest chain: %d\n", + op.u.hash_stats.entries, op.u.hash_stats.buckets_used, + op.u.hash_stats.buckets_total, op.u.hash_stats.max_chain_len); + + return err; } -int xc_flask_avc_cachestats(xc_interface *xc_handle, char *buf, int size) +int xc_flask_avc_cachestats(xc_interface *xch, char *buf, int size) { - int err; - flask_op_t op; + int err, n; + int i = 0; + DECLARE_FLASK_OP; + + n = snprintf(buf, size, "lookups hits misses allocations reclaims frees\n"); + buf += n; + size -= n; op.cmd = FLASK_AVC_CACHESTATS; - op.buf = buf; - op.size = size; - - if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) + while ( size > 0 ) { - free(buf); - return err; + op.u.cache_stats.cpu = i; + err = xc_flask_op(xch, &op); + if ( err && errno == ENOENT ) + return 0; + if ( err ) + return err; + n = snprintf(buf, size, "%u %u %u %u %u %u\n", + op.u.cache_stats.lookups, op.u.cache_stats.hits, + op.u.cache_stats.misses, op.u.cache_stats.allocations, + op.u.cache_stats.reclaims, op.u.cache_stats.frees); + buf += n; + size -= n; + i++; } return 0; } -int xc_flask_policyvers(xc_interface *xc_handle, char *buf, int size) +int xc_flask_policyvers(xc_interface *xch) { - int err; - flask_op_t op; - + DECLARE_FLASK_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; + return xc_flask_op(xch, &op); } -int xc_flask_getavc_threshold(xc_interface *xc_handle) +int xc_flask_getavc_threshold(xc_interface *xch) { - int err; - flask_op_t op; - char buf[20]; - int size = 20; - int threshold; - + DECLARE_FLASK_OP; 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; + return xc_flask_op(xch, &op); } -int xc_flask_setavc_threshold(xc_interface *xc_handle, int threshold) +int xc_flask_setavc_threshold(xc_interface *xch, int threshold) { - int err; - flask_op_t op; - char buf[20]; - int size = 20; - + DECLARE_FLASK_OP; op.cmd = FLASK_SETAVC_THRESHOLD; - op.buf = buf; - op.size = size; + op.u.setavc_threshold.threshold = threshold; - snprintf(buf, size, "%i", threshold); - - if ( (err = xc_flask_op(xc_handle, &op)) != 0 ) - return err; - - return 0; + return xc_flask_op(xch, &op); } /* diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h index 3687561..7b83ef3 100644 --- a/tools/libxc/xc_private.h +++ b/tools/libxc/xc_private.h @@ -42,11 +42,13 @@ #define DECLARE_DOMCTL struct xen_domctl domctl = { 0 } #define DECLARE_SYSCTL struct xen_sysctl sysctl = { 0 } #define DECLARE_PHYSDEV_OP struct physdev_op physdev_op = { 0 } +#define DECLARE_FLASK_OP struct xen_flask_op op = { 0 } #else #define DECLARE_HYPERCALL privcmd_hypercall_t hypercall #define DECLARE_DOMCTL struct xen_domctl domctl #define DECLARE_SYSCTL struct xen_sysctl sysctl #define DECLARE_PHYSDEV_OP struct physdev_op physdev_op +#define DECLARE_FLASK_OP struct xen_flask_op op #endif #undef PAGE_SHIFT diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 1e7c32b..6b3202e 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -1328,7 +1328,7 @@ int xc_sysctl(xc_interface *xch, struct xen_sysctl *sysctl); int xc_version(xc_interface *xch, int cmd, void *arg); -int xc_flask_op(xc_interface *xch, flask_op_t *op); +int xc_flask_op(xc_interface *xch, xen_flask_op_t *op); /* * Subscribe to state changes in a domain via evtchn. @@ -1976,7 +1976,7 @@ int xc_flask_access(xc_interface *xc_handle, const char *scon, const char *tcon, 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_policyvers(xc_interface *xc_handle); 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); diff --git a/xen/include/public/xsm/flask_op.h b/xen/include/public/xsm/flask_op.h index 416ac08..83dcd99 100644 --- a/xen/include/public/xsm/flask_op.h +++ b/xen/include/public/xsm/flask_op.h @@ -25,6 +25,118 @@ #ifndef __FLASK_OP_H__ #define __FLASK_OP_H__ +#define XEN_FLASK_INTERFACE_VERSION 1 + +struct xen_flask_load { + XEN_GUEST_HANDLE(char) buffer; + uint32_t size; +}; + +struct xen_flask_setenforce { + uint32_t enforcing; +}; + +struct xen_flask_sid_context { + /* IN/OUT: sid to convert to/from string */ + uint32_t sid; + /* IN: size of the context buffer + * OUT: actual size of the output context string + */ + uint32_t size; + XEN_GUEST_HANDLE(char) context; +}; + +struct xen_flask_access { + /* IN: access request */ + uint32_t ssid; + uint32_t tsid; + uint32_t tclass; + uint32_t req; + /* OUT: AVC data */ + uint32_t allowed; + uint32_t audit_allow; + uint32_t audit_deny; + uint32_t seqno; +}; + +struct xen_flask_transition { + /* IN: transition SIDs and class */ + uint32_t ssid; + uint32_t tsid; + uint32_t tclass; + /* OUT: new SID */ + uint32_t newsid; +}; + +struct xen_flask_userlist { + /* IN: starting SID for list */ + uint32_t start_sid; + /* IN: size of user string and output buffer + * OUT: number of SIDs returned */ + uint32_t size; + union { + /* IN: user to enumerate SIDs */ + XEN_GUEST_HANDLE(char) user; + /* OUT: SID list */ + XEN_GUEST_HANDLE(uint32) sids; + } u; +}; + +struct xen_flask_boolean { + /* IN/OUT: numeric identifier for boolean [GET/SET] + * If -1, name will be used and bool_id will be filled in. */ + uint32_t bool_id; + /* OUT: current enforcing value of boolean [GET/SET] */ + uint8_t enforcing; + /* OUT: pending value of boolean [GET/SET] */ + uint8_t pending; + /* IN: new value of boolean [SET] */ + uint8_t new_value; + /* IN: commit new value instead of only setting pending [SET] */ + uint8_t commit; + /* IN: size of boolean name buffer [GET/SET] + * OUT: actual size of name [GET only] */ + uint32_t size; + /* IN: if bool_id is -1, used to find boolean [GET/SET] + * OUT: textual name of boolean [GET only] + */ + XEN_GUEST_HANDLE(char) name; +}; + +struct xen_flask_setavc_threshold { + /* IN */ + uint32_t threshold; +}; + +struct xen_flask_hash_stats { + /* OUT */ + uint32_t entries; + uint32_t buckets_used; + uint32_t buckets_total; + uint32_t max_chain_len; +}; + +struct xen_flask_cache_stats { + /* IN */ + uint32_t cpu; + /* OUT */ + uint32_t lookups; + uint32_t hits; + uint32_t misses; + uint32_t allocations; + uint32_t reclaims; + uint32_t frees; +}; + +struct xen_flask_ocontext { + /* IN */ + uint32_t ocon; + uint32_t sid; + uint64_t low, high; +}; + +struct xen_flask_op { + uint32_t cmd; #define FLASK_LOAD 1 #define FLASK_GETENFORCE 2 #define FLASK_SETENFORCE 3 @@ -47,18 +159,26 @@ #define FLASK_MEMBER 20 #define FLASK_ADD_OCONTEXT 21 #define FLASK_DEL_OCONTEXT 22 -#define FLASK_GETBOOL_NAMED 23 -#define FLASK_GETBOOL2 24 -#define FLASK_SETBOOL_NAMED 25 - -#define FLASK_LAST FLASK_SETBOOL_NAMED - -typedef struct flask_op { - uint32_t cmd; - uint32_t size; - char *buf; -} flask_op_t; - -DEFINE_XEN_GUEST_HANDLE(flask_op_t); + uint32_t interface_version; /* XEN_FLASK_INTERFACE_VERSION */ + union { + struct xen_flask_load load; + struct xen_flask_setenforce enforce; + /* FLASK_CONTEXT_TO_SID and FLASK_SID_TO_CONTEXT */ + struct xen_flask_sid_context sid_context; + struct xen_flask_access access; + /* FLASK_CREATE, FLASK_RELABEL, FLASK_MEMBER */ + struct xen_flask_transition transition; + struct xen_flask_userlist userlist; + /* FLASK_GETBOOL, FLASK_SETBOOL */ + struct xen_flask_boolean boolean; + struct xen_flask_setavc_threshold setavc_threshold; + struct xen_flask_hash_stats hash_stats; + struct xen_flask_cache_stats cache_stats; + /* FLASK_ADD_OCONTEXT, FLASK_DEL_OCONTEXT */ + struct xen_flask_ocontext ocontext; + } u; +}; +typedef struct xen_flask_op xen_flask_op_t; +DEFINE_XEN_GUEST_HANDLE(xen_flask_op_t); #endif diff --git a/xen/xsm/flask/avc.c b/xen/xsm/flask/avc.c index 3a60a3a..74f160d 100644 --- a/xen/xsm/flask/avc.c +++ b/xen/xsm/flask/avc.c @@ -28,6 +28,7 @@ #include <xen/rcupdate.h> #include <asm/atomic.h> #include <asm/current.h> +#include <public/xsm/flask_op.h> #include "avc.h" #include "avc_ss.h" @@ -251,7 +252,7 @@ void __init avc_init(void) printk("AVC INITIALIZED\n"); } -int avc_get_hash_stats(char *buf, uint32_t size) +int avc_get_hash_stats(struct xen_flask_hash_stats *arg) { int i, chain_len, max_chain_len, slots_used; struct avc_node *node; @@ -279,10 +280,12 @@ int avc_get_hash_stats(char *buf, uint32_t size) rcu_read_unlock(&avc_rcu_lock); - return snprintf(buf, size, "entries: %d\nbuckets used: %d/%d\n" - "longest chain: %d\n", - atomic_read(&avc_cache.active_nodes), - slots_used, AVC_CACHE_SLOTS, max_chain_len); + arg->entries = atomic_read(&avc_cache.active_nodes); + arg->buckets_used = slots_used; + arg->buckets_total = AVC_CACHE_SLOTS; + arg->max_chain_len = max_chain_len; + + return 0; } static void avc_node_free(struct rcu_head *rhead) diff --git a/xen/xsm/flask/flask_op.c b/xen/xsm/flask/flask_op.c index 64d9ec5..00a0af2 100644 --- a/xen/xsm/flask/flask_op.c +++ b/xen/xsm/flask/flask_op.c @@ -30,48 +30,21 @@ integer_param("flask_enabled", flask_enabled); #endif #define MAX_POLICY_SIZE 0x4000000 -#define FLASK_COPY_IN \ - ( \ - 1UL<<FLASK_LOAD | \ - 1UL<<FLASK_SETENFORCE | \ - 1UL<<FLASK_CONTEXT_TO_SID | \ - 1UL<<FLASK_SID_TO_CONTEXT | \ - 1UL<<FLASK_ACCESS | \ - 1UL<<FLASK_CREATE | \ - 1UL<<FLASK_RELABEL | \ - 1UL<<FLASK_USER | \ - 1UL<<FLASK_GETBOOL | \ - 1UL<<FLASK_SETBOOL | \ - 1UL<<FLASK_COMMITBOOLS | \ - 1UL<<FLASK_DISABLE | \ - 1UL<<FLASK_SETAVC_THRESHOLD | \ - 1UL<<FLASK_MEMBER | \ - 1UL<<FLASK_ADD_OCONTEXT | \ - 1UL<<FLASK_DEL_OCONTEXT | \ - 1UL<<FLASK_GETBOOL_NAMED | \ - 1UL<<FLASK_GETBOOL2 | \ - 1UL<<FLASK_SETBOOL_NAMED \ - ) #define FLASK_COPY_OUT \ ( \ - 1UL<<FLASK_GETENFORCE | \ 1UL<<FLASK_CONTEXT_TO_SID | \ 1UL<<FLASK_SID_TO_CONTEXT | \ 1UL<<FLASK_ACCESS | \ 1UL<<FLASK_CREATE | \ 1UL<<FLASK_RELABEL | \ 1UL<<FLASK_USER | \ - 1UL<<FLASK_POLICYVERS | \ 1UL<<FLASK_GETBOOL | \ - 1UL<<FLASK_MLS | \ - 1UL<<FLASK_GETAVC_THRESHOLD | \ + 1UL<<FLASK_SETBOOL | \ 1UL<<FLASK_AVC_HASHSTATS | \ 1UL<<FLASK_AVC_CACHESTATS | \ 1UL<<FLASK_MEMBER | \ - 1UL<<FLASK_GETBOOL_NAMED | \ - 1UL<<FLASK_GETBOOL2 \ - ) + 0) static DEFINE_SPINLOCK(sel_sem); @@ -96,412 +69,186 @@ static int domain_has_security(struct domain *d, u32 perms) perms, NULL); } -static int flask_security_user(char *buf, uint32_t size) -{ - char *page = NULL; - char *con, *user, *ptr; - u32 sid, *sids; - int length; - char *newcon; - int i, rc; - u32 len, nsids; - - length = domain_has_security(current->domain, SECURITY__COMPUTE_USER); - if ( length ) - return length; - - length = -ENOMEM; - con = xmalloc_array(char, size+1); - if ( !con ) - return length; - memset(con, 0, size+1); - - user = xmalloc_array(char, size+1); - if ( !user ) - goto out; - memset(user, 0, size+1); - - length = -ENOMEM; - page = xmalloc_bytes(PAGE_SIZE); - if ( !page ) - goto out2; - memset(page, 0, PAGE_SIZE); - - length = -EINVAL; - if ( sscanf(buf, "%s %s", con, user) != 2 ) - goto out2; - - length = security_context_to_sid(con, strlen(con)+1, &sid); - if ( length < 0 ) - goto out2; - - length = security_get_user_sids(sid, user, &sids, &nsids); - if ( length < 0 ) - goto out2; - - length = snprintf(page, PAGE_SIZE, "%u", nsids) + 1; - ptr = page + length; - for ( i = 0; i < nsids; i++ ) - { - rc = security_sid_to_context(sids[i], &newcon, &len); - if ( rc ) - { - length = rc; - goto out3; - } - if ( (length + len) >= PAGE_SIZE ) - { - xfree(newcon); - length = -ERANGE; - goto out3; - } - memcpy(ptr, newcon, len); - xfree(newcon); - ptr += len; - length += len; - } - - if ( length > size ) - { - printk( "%s: context size (%u) exceeds payload " - "max\n", __FUNCTION__, length); - length = -ERANGE; - goto out3; - } - - memset(buf, 0, size); - memcpy(buf, page, length); - - out3: - xfree(sids); - out2: - if ( page ) - xfree(page); - xfree(user); - out: - xfree(con); - return length; -} - -static int flask_security_relabel(char *buf, uint32_t size) +static int flask_copyin_string(XEN_GUEST_HANDLE(char) u_buf, char **buf, uint32_t size) { - char *scon, *tcon; - u32 ssid, tsid, newsid; - u16 tclass; - int length; - char *newcon; - u32 len; + char *tmp = xmalloc_bytes(size + 1); + if ( !tmp ) + return -ENOMEM; - length = domain_has_security(current->domain, SECURITY__COMPUTE_RELABEL); - if ( length ) - return length; - - length = -ENOMEM; - scon = xmalloc_array(char, size+1); - if ( !scon ) - return length; - memset(scon, 0, size+1); - - tcon = xmalloc_array(char, size+1); - if ( !tcon ) - goto out; - memset(tcon, 0, size+1); - - length = -EINVAL; - if ( sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3 ) - goto out2; - - length = security_context_to_sid(scon, strlen(scon)+1, &ssid); - if ( length < 0 ) - goto out2; - length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid); - if ( length < 0 ) - goto out2; - - length = security_change_sid(ssid, tsid, tclass, &newsid); - if ( length < 0 ) - goto out2; - - length = security_sid_to_context(newsid, &newcon, &len); - if ( length < 0 ) - goto out2; - - if ( len > size ) + if ( copy_from_guest(tmp, u_buf, size) ) { - printk( "%s: context size (%u) exceeds payload " - "max\n", __FUNCTION__, len); - length = -ERANGE; - goto out3; + xfree(tmp); + return -EFAULT; } + tmp[size] = 0; - memset(buf, 0, size); - memcpy(buf, newcon, len); - length = len; - - out3: - xfree(newcon); - out2: - xfree(tcon); - out: - xfree(scon); - return length; + *buf = tmp; + return 0; } -static int flask_security_create(char *buf, uint32_t size) +static int flask_security_user(struct xen_flask_userlist *arg) { - char *scon, *tcon; - u32 ssid, tsid, newsid; - u16 tclass; - int length; - char *newcon; - u32 len; + char *user; + u32 *sids; + u32 nsids; + int rv; - length = domain_has_security(current->domain, SECURITY__COMPUTE_CREATE); - if ( length ) - return length; + rv = domain_has_security(current->domain, SECURITY__COMPUTE_USER); + if ( rv ) + return rv; - length = -ENOMEM; - scon = xmalloc_array(char, size+1); - if ( !scon ) - return length; - memset(scon, 0, size+1); + rv = flask_copyin_string(arg->u.user, &user, arg->size); + if ( rv ) + return rv; - tcon = xmalloc_array(char, size+1); - if ( !tcon ) + rv = security_get_user_sids(arg->start_sid, user, &sids, &nsids); + if ( rv < 0 ) goto out; - memset(tcon, 0, size+1); - - length = -EINVAL; - if ( sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3 ) - goto out2; - - length = security_context_to_sid(scon, strlen(scon)+1, &ssid); - if ( length < 0 ) - goto out2; - length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid); - if ( length < 0 ) - goto out2; + if ( nsids * sizeof(sids[0]) > arg->size ) + nsids = arg->size / sizeof(sids[0]); - length = security_transition_sid(ssid, tsid, tclass, &newsid); - if ( length < 0 ) - goto out2; + arg->size = nsids; - length = security_sid_to_context(newsid, &newcon, &len); - if ( length < 0 ) - goto out2; - - if ( len > size ) - { - printk( "%s: context size (%u) exceeds payload " - "max\n", __FUNCTION__, len); - length = -ERANGE; - goto out3; - } + if ( copy_to_guest(arg->u.sids, sids, nsids) ) + rv = -EFAULT; - memset(buf, 0, size); - memcpy(buf, newcon, len); - length = len; - - out3: - xfree(newcon); - out2: - xfree(tcon); + xfree(sids); out: - xfree(scon); - return length; + xfree(user); + return rv; } -static int flask_security_access(char *buf, uint32_t size) +static int flask_security_relabel(struct xen_flask_transition *arg) { - char *scon, *tcon; - u32 ssid, tsid; - u16 tclass; - u32 req; - struct av_decision avd; - int length; + int rv; - length = domain_has_security(current->domain, SECURITY__COMPUTE_AV); - if ( length ) - return length; - - length = -ENOMEM; - scon = xmalloc_array(char, size+1); - if (!scon) - return length; - memset(scon, 0, size+1); - - tcon = xmalloc_array(char, size+1); - if ( !tcon ) - goto out; - memset( tcon, 0, size+1 ); - - length = -EINVAL; - if (sscanf(buf, "%s %s %hu %x", scon, tcon, &tclass, &req) != 4) - goto out2; - - length = security_context_to_sid(scon, strlen(scon)+1, &ssid); - if ( length < 0 ) - goto out2; - - length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid); - if ( length < 0 ) - goto out2; + rv = domain_has_security(current->domain, SECURITY__COMPUTE_RELABEL); + if ( rv ) + return rv; - length = security_compute_av(ssid, tsid, tclass, req, &avd); - if ( length < 0 ) - goto out2; + rv = security_change_sid(arg->ssid, arg->tsid, arg->tclass, &arg->newsid); - memset(buf, 0, size); - length = snprintf(buf, size, "%x %x %x %x %u", - avd.allowed, 0xffffffff, - avd.auditallow, avd.auditdeny, - avd.seqno); - - out2: - xfree(tcon); - out: - xfree(scon); - return length; + return rv; } -static int flask_security_member(char *buf, uint32_t size) +static int flask_security_create(struct xen_flask_transition *arg) { - char *scon, *tcon; - u32 ssid, tsid, newsid; - u16 tclass; - int length; - char *newcon; - u32 len; + int rv; - length = domain_has_security(current->domain, SECURITY__COMPUTE_MEMBER); - if ( length ) - return length; + rv = domain_has_security(current->domain, SECURITY__COMPUTE_CREATE); + if ( rv ) + return rv; - length = -ENOMEM; - scon = xmalloc_array(char, size+1); - if ( !scon ) - return length; - memset(scon, 0, size+1); + rv = security_transition_sid(arg->ssid, arg->tsid, arg->tclass, &arg->newsid); - tcon = xmalloc_array(char, size+1); - if ( !tcon ) - goto out; - memset(tcon, 0, size+1); + return rv; +} - length = -EINVAL; - if ( sscanf(buf, "%s, %s, %hu", scon, tcon, &tclass) != 3 ) - goto out2; +static int flask_security_access(struct xen_flask_access *arg) +{ + struct av_decision avd; + int rv; - length = security_context_to_sid(scon, strlen(scon)+1, &ssid); - if ( length < 0 ) - goto out2; + rv = domain_has_security(current->domain, SECURITY__COMPUTE_AV); + if ( rv ) + return rv; - length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid); - if ( length < 0 ) - goto out2; + rv = security_compute_av(arg->ssid, arg->tsid, arg->tclass, arg->req, &avd); + if ( rv < 0 ) + return rv; - length = security_member_sid(ssid, tsid, tclass, &newsid); - if ( length < 0 ) - goto out2; + arg->allowed = avd.allowed; + arg->audit_allow = avd.auditallow; + arg->audit_deny = avd.auditdeny; + arg->seqno = avd.seqno; + + return rv; +} - length = security_sid_to_context(newsid, &newcon, &len); - if ( length < 0 ) - goto out2; +static int flask_security_member(struct xen_flask_transition *arg) +{ + int rv; - if ( len > size ) - { - printk("%s: context size (%u) exceeds payload " - "max\n", __FUNCTION__, len); - length = -ERANGE; - goto out3; - } + rv = domain_has_security(current->domain, SECURITY__COMPUTE_MEMBER); + if ( rv ) + return rv; - memset(buf, 0, size); - memcpy(buf, newcon, len); - length = len; + rv = security_member_sid(arg->ssid, arg->tsid, arg->tclass, &arg->newsid); - out3: - xfree(newcon); - out2: - xfree(tcon); - out: - xfree(scon); - return length; + return rv; } -static int flask_security_setenforce(char *buf, uint32_t count) +static int flask_security_setenforce(struct xen_flask_setenforce *arg) { - int length; - int new_value; + int enforce = !!(arg->enforcing); + int rv; - if ( sscanf(buf, "%d", &new_value) != 1 ) - return -EINVAL; + if ( enforce == flask_enforcing ) + return 0; - if ( new_value != flask_enforcing ) - { - length = domain_has_security(current->domain, SECURITY__SETENFORCE); - if ( length ) - goto out; - flask_enforcing = new_value; - if ( flask_enforcing ) - avc_ss_reset(0); - } - length = count; + rv = domain_has_security(current->domain, SECURITY__SETENFORCE); + if ( rv ) + return rv; - out: - return length; + flask_enforcing = enforce; + + if ( flask_enforcing ) + avc_ss_reset(0); + + return 0; } -static int flask_security_context(char *buf, uint32_t count) +static int flask_security_context(struct xen_flask_sid_context *arg) { - u32 sid; - int length; + int rv; + char *buf; - length = domain_has_security(current->domain, SECURITY__CHECK_CONTEXT); - if ( length ) - goto out; + rv = domain_has_security(current->domain, SECURITY__CHECK_CONTEXT); + if ( rv ) + return rv; - length = security_context_to_sid(buf, count, &sid); - if ( length < 0 ) - goto out; + rv = flask_copyin_string(arg->context, &buf, arg->size); + if ( rv ) + return rv; - memset(buf, 0, count); - length = snprintf(buf, count, "%u", sid); + rv = security_context_to_sid(buf, arg->size, &arg->sid); + if ( rv < 0 ) + goto out; out: - return length; + xfree(buf); + + return rv; } -static int flask_security_sid(char *buf, uint32_t count) +static int flask_security_sid(struct xen_flask_sid_context *arg) { + int rv; char *context; - u32 sid; u32 len; - int length; - length = domain_has_security(current->domain, SECURITY__CHECK_CONTEXT); - if ( length ) - goto out; + rv = domain_has_security(current->domain, SECURITY__CHECK_CONTEXT); + if ( rv ) + return rv; - if ( sscanf(buf, "%u", &sid) != 1 ) - goto out; + rv = security_sid_to_context(arg->sid, &context, &len); + if ( rv < 0 ) + return rv; - length = security_sid_to_context(sid, &context, &len); - if ( length < 0 ) - goto out; + rv = 0; - if ( len > count ) - return -ERANGE; + if ( len > arg->size ) + rv = -ERANGE; - memset(buf, 0, count); - memcpy(buf, context, len); - length = len; + arg->size = len; + + if ( !rv && copy_to_guest(arg->context, context, len) ) + rv = -EFAULT; xfree(context); - out: - return length; + return rv; } int flask_disable(void) @@ -530,229 +277,154 @@ int flask_disable(void) return 0; } -static int flask_security_disable(char *buf, uint32_t count) -{ - int length; - int new_value; - - length = -EINVAL; - if ( sscanf(buf, "%d", &new_value) != 1 ) - goto out; - - if ( new_value ) - { - length = flask_disable(); - if ( length < 0 ) - goto out; - } - - length = count; - - out: - return length; -} - -static int flask_security_setavc_threshold(char *buf, uint32_t count) +static int flask_security_setavc_threshold(struct xen_flask_setavc_threshold *arg) { - int ret; - int new_value; - - if ( sscanf(buf, "%u", &new_value) != 1 ) - { - ret = -EINVAL; - goto out; - } + int rv = 0; - if ( new_value != avc_cache_threshold ) + if ( arg->threshold != avc_cache_threshold ) { - ret = domain_has_security(current->domain, SECURITY__SETSECPARAM); - if ( ret ) + rv = domain_has_security(current->domain, SECURITY__SETSECPARAM); + if ( rv ) goto out; - avc_cache_threshold = new_value; + avc_cache_threshold = arg->threshold; } - ret = count; out: - return ret; + return rv; } -static int flask_security_set_bool(char *buf, uint32_t count) +static int flask_security_resolve_bool(struct xen_flask_boolean *arg) { - int length = -EFAULT; - unsigned int i, new_value; - - spin_lock(&sel_sem); - - length = domain_has_security(current->domain, SECURITY__SETBOOL); - if ( length ) - goto out; - - length = -EINVAL; - if ( sscanf(buf, "%d %d", &i, &new_value) != 2 ) - goto out; + char *name; + int rv; - if (!bool_pending_values) - flask_security_make_bools(); + if ( arg->bool_id != -1 ) + return 0; - if ( i >= bool_num ) - goto out; + rv = flask_copyin_string(arg->name, &name, arg->size); + if ( rv ) + return rv; - if ( new_value ) - new_value = 1; + arg->bool_id = security_find_bool(name); + arg->size = 0; - bool_pending_values[i] = new_value; - length = count; + xfree(name); - out: - spin_unlock(&sel_sem); - return length; + return 0; } -static int flask_security_set_bool_name(char *buf, uint32_t count) +static int flask_security_set_bool(struct xen_flask_boolean *arg) { - int rv, num; - int i, new_value, commit; - int *values = NULL; - char *name; - - name = xmalloc_bytes(count); - if ( name == NULL ) - return -ENOMEM; + int rv; - spin_lock(&sel_sem); + rv = flask_security_resolve_bool(arg); + if ( rv ) + return rv; rv = domain_has_security(current->domain, SECURITY__SETBOOL); if ( rv ) - goto out; - - rv = -EINVAL; - if ( sscanf(buf, "%s %d %d", name, &new_value, &commit) != 3 ) - goto out; + return rv; - i = security_find_bool(name); - if ( i < 0 ) - goto out; + spin_lock(&sel_sem); - if ( new_value ) - new_value = 1; + if ( arg->commit ) + { + int num; + int *values; - if ( commit ) { rv = security_get_bools(&num, NULL, &values); if ( rv != 0 ) goto out; - values[i] = new_value; - if (bool_pending_values) - bool_pending_values[i] = new_value; + + if ( arg->bool_id >= num ) + { + rv = -ENOENT; + goto out; + } + values[arg->bool_id] = !!(arg->new_value); + + arg->enforcing = arg->pending = !!(arg->new_value); + + if ( bool_pending_values ) + bool_pending_values[arg->bool_id] = !!(arg->new_value); + rv = security_set_bools(num, values); xfree(values); - } else { - if (!bool_pending_values) + } + else + { + if ( !bool_pending_values ) flask_security_make_bools(); - bool_pending_values[i] = new_value; - rv = count; + if ( arg->bool_id >= bool_num ) + goto out; + + bool_pending_values[arg->bool_id] = !!(arg->new_value); + arg->pending = !!(arg->new_value); + arg->enforcing = security_get_bool_value(arg->bool_id); + + rv = 0; } out: - xfree(name); spin_unlock(&sel_sem); return rv; } -static int flask_security_commit_bools(char *buf, uint32_t count) +static int flask_security_commit_bools(void) { - int length = -EFAULT; - int new_value; + int rv; spin_lock(&sel_sem); - length = domain_has_security(current->domain, SECURITY__SETBOOL); - if ( length ) - goto out; - - length = -EINVAL; - if ( sscanf(buf, "%d", &new_value) != 1 ) + rv = domain_has_security(current->domain, SECURITY__SETBOOL); + if ( rv ) goto out; - if ( new_value && bool_pending_values ) - security_set_bools(bool_num, bool_pending_values); + if ( bool_pending_values ) + rv = security_set_bools(bool_num, bool_pending_values); - length = count; - out: spin_unlock(&sel_sem); - return length; + return rv; } -static int flask_security_get_bool(char *buf, uint32_t count, int named) +static int flask_security_get_bool(struct xen_flask_boolean *arg) { - int length; - int i, cur_enforcing, pend_enforcing; - char* name = NULL; - - spin_lock(&sel_sem); - - length = -EINVAL; - if ( sscanf(buf, "%d", &i) != 1 ) - goto out; + int rv; - cur_enforcing = security_get_bool_value(i); - if ( cur_enforcing < 0 ) - { - length = cur_enforcing; - goto out; - } + rv = flask_security_resolve_bool(arg); + if ( rv ) + return rv; - if ( bool_pending_values ) - pend_enforcing = bool_pending_values[i]; - else - pend_enforcing = cur_enforcing; + spin_lock(&sel_sem); - if ( named ) - name = security_get_bool_name(i); - if ( named && !name ) + rv = security_get_bool_value(arg->bool_id); + if ( rv < 0 ) goto out; - memset(buf, 0, count); - if ( named ) - length = snprintf(buf, count, "%d %d %s", cur_enforcing, - pend_enforcing, name); - else - length = snprintf(buf, count, "%d %d", cur_enforcing, - pend_enforcing); + arg->enforcing = rv; - out: - xfree(name); - spin_unlock(&sel_sem); - return length; -} + if ( bool_pending_values ) + arg->pending = bool_pending_values[arg->bool_id]; + else + arg->pending = rv; -static int flask_security_get_bool_name(char *buf, uint32_t count) -{ - int rv = -ENOENT; - int i, cur_enforcing, pend_enforcing; - - spin_lock(&sel_sem); - - i = security_find_bool(buf); - if ( i < 0 ) - goto out; + rv = 0; - cur_enforcing = security_get_bool_value(i); - if ( cur_enforcing < 0 ) + if ( arg->size ) { - rv = cur_enforcing; - goto out; + char *nameout = security_get_bool_name(arg->bool_id); + size_t nameout_len = strlen(nameout); + if ( nameout_len > arg->size ) + rv = -ERANGE; + arg->size = nameout_len; + + if ( !rv && copy_to_guest(arg->name, nameout, nameout_len) ) + rv = -EFAULT; + xfree(nameout); } - if ( bool_pending_values ) - pend_enforcing = bool_pending_values[i]; - else - pend_enforcing = cur_enforcing; - - memset(buf, 0, count); - rv = snprintf(buf, count, "%d %d", cur_enforcing, pend_enforcing); - out: spin_unlock(&sel_sem); return rv; @@ -779,380 +451,212 @@ static int flask_security_make_bools(void) #ifdef FLASK_AVC_STATS -static int flask_security_avc_cachestats(char *buf, uint32_t count) +static int flask_security_avc_cachestats(struct xen_flask_cache_stats *arg) { - char *page = NULL; - int len = 0; - int length = 0; - int cpu; struct avc_cache_stats *st; - page = (char *)xmalloc_bytes(PAGE_SIZE); - if ( !page ) - return -ENOMEM; - memset(page, 0, PAGE_SIZE); + if ( arg->cpu > nr_cpu_ids ) + return -ENOENT; + if ( !cpu_online(arg->cpu) ) + return -ENOENT; - len = snprintf(page, PAGE_SIZE, "lookups hits misses allocations reclaims " - "frees\n"); - if ( len > count ) { - length = -EINVAL; - goto out; - } - - memcpy(buf, page, len); - buf += len; - length += len; - count -= len; + st = &per_cpu(avc_cache_stats, arg->cpu); - for_each_online_cpu ( cpu ) - { - st = &per_cpu(avc_cache_stats, cpu); + arg->lookups = st->lookups; + arg->hits = st->hits; + arg->misses = st->misses; + arg->allocations = st->allocations; + arg->reclaims = st->reclaims; + arg->frees = st->frees; - len = snprintf(page, PAGE_SIZE, "%u %u %u %u %u %u\n", st->lookups, - st->hits, st->misses, st->allocations, - st->reclaims, st->frees); - if ( len > count ) { - length = -EINVAL; - goto out; - } - memcpy(buf, page, len); - buf += len; - length += len; - count -= len; - } - - out: - xfree(page); - return length; + return 0; } #endif -static int flask_security_load(char *buf, uint32_t count) +static int flask_security_load(struct xen_flask_load *load) { int ret; - int length; - - spin_lock(&sel_sem); + void *buf = NULL; - length = domain_has_security(current->domain, SECURITY__LOAD_POLICY); - if ( length ) - goto out; - - length = security_load_policy(buf, count); - if ( length ) - goto out; - - ret = flask_security_make_bools(); + ret = domain_has_security(current->domain, SECURITY__LOAD_POLICY); if ( ret ) - length = ret; - else - length = count; + return ret; - out: - spin_unlock(&sel_sem); - return length; -} - -static int flask_ocontext_del(char *buf, uint32_t size) -{ - int len = 0; - char *ocontext; - unsigned long low = 0; - unsigned long high = 0; - - len = domain_has_security(current->domain, SECURITY__DEL_OCONTEXT); - if ( len ) - return len; + if ( load->size > MAX_POLICY_SIZE ) + return -EINVAL; - if ( (ocontext = xmalloc_bytes(size) ) == NULL ) + buf = xmalloc_bytes(load->size); + if ( !buf ) return -ENOMEM; - len = sscanf(buf, "%s %lu %lu", ocontext, &low, &high); - if ( len < 2 ) + if ( copy_from_guest(buf, load->buffer, load->size) ) { - len = -EINVAL; - goto out; + ret = -EFAULT; + goto out_free; } - else if ( len == 2 ) - high = low; - if ( low > high ) - { - len = -EINVAL; + spin_lock(&sel_sem); + + ret = security_load_policy(buf, load->size); + if ( ret ) goto out; - } - len = security_ocontext_del(ocontext, low, high); + xfree(bool_pending_values); + bool_pending_values = NULL; + ret = 0; + out: - xfree(ocontext); - return len; + spin_unlock(&sel_sem); + out_free: + xfree(buf); + return ret; } -static int flask_ocontext_add(char *buf, uint32_t size) +static int flask_ocontext_del(struct xen_flask_ocontext *arg) { - int len = 0; - u32 sid = 0; - unsigned long low = 0; - unsigned long high = 0; - char *scontext; - char *ocontext; - - len = domain_has_security(current->domain, SECURITY__ADD_OCONTEXT); - if ( len ) - return len; - - if ( (scontext = xmalloc_bytes(size) ) == NULL ) - return -ENOMEM; + int rv; - if ( (ocontext = xmalloc_bytes(size) ) == NULL ) - { - xfree(scontext); - return -ENOMEM; - } - - memset(scontext, 0, size); - memset(ocontext, 0, size); + if ( arg->low > arg->high ) + return -EINVAL; - len = sscanf(buf, "%s %s %lu %lu", ocontext, scontext, &low, &high); - if ( len < 3 ) - { - len = -EINVAL; - goto out; - } - else if ( len == 3 ) - high = low; + rv = domain_has_security(current->domain, SECURITY__DEL_OCONTEXT); + if ( rv ) + return rv; - if ( low > high ) - { - len = -EINVAL; - goto out; - } - len = security_context_to_sid(scontext, strlen(scontext)+1, &sid); - if ( len < 0 ) - { - len = -EINVAL; - goto out; - } - len = security_ocontext_add(ocontext, low, high, sid); - out: - xfree(ocontext); - xfree(scontext); - return len; + return security_ocontext_del(arg->ocon, arg->low, arg->high); } -long do_flask_op(XEN_GUEST_HANDLE(xsm_op_t) u_flask_op) +static int flask_ocontext_add(struct xen_flask_ocontext *arg) { - flask_op_t curop, *op = &curop; - int rc = 0; - int length = 0; - char *arg = NULL; + int rv; - if ( copy_from_guest(op, u_flask_op, 1) ) - return -EFAULT; - - if ( op->cmd > FLASK_LAST) + if ( arg->low > arg->high ) return -EINVAL; - if ( op->size > MAX_POLICY_SIZE ) - return -EINVAL; + rv = domain_has_security(current->domain, SECURITY__ADD_OCONTEXT); + if ( rv ) + return rv; - if ( (op->buf == NULL && op->size != 0) || - (op->buf != NULL && op->size == 0) ) - return -EINVAL; + return security_ocontext_add(arg->ocon, arg->low, arg->high, arg->sid); +} - arg = xmalloc_bytes(op->size + 1); - if ( !arg ) - return -ENOMEM; +long do_flask_op(XEN_GUEST_HANDLE(xsm_op_t) u_flask_op) +{ + xen_flask_op_t op; + int rv; - memset(arg, 0, op->size + 1); + if ( copy_from_guest(&op, u_flask_op, 1) ) + return -EFAULT; - if ( (FLASK_COPY_IN&(1UL<<op->cmd)) && op->buf != NULL && - copy_from_guest(arg, guest_handle_from_ptr(op->buf, char), op->size) ) - { - rc = -EFAULT; - goto out; - } + if ( op.interface_version != XEN_FLASK_INTERFACE_VERSION ) + return -ENOSYS; - switch ( op->cmd ) + switch ( op.cmd ) { - case FLASK_LOAD: - { - length = flask_security_load(arg, op->size); - } - break; - + rv = flask_security_load(&op.u.load); + break; + case FLASK_GETENFORCE: - { - length = snprintf(arg, op->size, "%d", flask_enforcing); - } - break; + rv = flask_enforcing; + break; case FLASK_SETENFORCE: - { - length = flask_security_setenforce(arg, op->size); - } - break; + rv = flask_security_setenforce(&op.u.enforce); + break; case FLASK_CONTEXT_TO_SID: - { - length = flask_security_context(arg, op->size); - } - break; + rv = flask_security_context(&op.u.sid_context); + break; case FLASK_SID_TO_CONTEXT: - { - length = flask_security_sid(arg, op->size); - } - break; + rv = flask_security_sid(&op.u.sid_context); + break; case FLASK_ACCESS: - { - length = flask_security_access(arg, op->size); - } - break; + rv = flask_security_access(&op.u.access); + break; case FLASK_CREATE: - { - length = flask_security_create(arg, op->size); - } - break; + rv = flask_security_create(&op.u.transition); + break; case FLASK_RELABEL: - { - length = flask_security_relabel(arg, op->size); - } - break; + rv = flask_security_relabel(&op.u.transition); + break; case FLASK_USER: - { - length = flask_security_user(arg, op->size); - } - break; + rv = flask_security_user(&op.u.userlist); + break; case FLASK_POLICYVERS: - { - length = snprintf(arg, op->size, "%d", POLICYDB_VERSION_MAX); - } - break; + rv = POLICYDB_VERSION_MAX; + break; case FLASK_GETBOOL: - { - length = flask_security_get_bool(arg, op->size, 0); - } - break; + rv = flask_security_get_bool(&op.u.boolean); + break; case FLASK_SETBOOL: - { - length = flask_security_set_bool(arg, op->size); - } - break; + rv = flask_security_set_bool(&op.u.boolean); + break; case FLASK_COMMITBOOLS: - { - length = flask_security_commit_bools(arg, op->size); - } - break; + rv = flask_security_commit_bools(); + break; case FLASK_MLS: - { - length = snprintf(arg, op->size, "%d", flask_mls_enabled); - } - break; + rv = flask_mls_enabled; + break; case FLASK_DISABLE: - { - length = flask_security_disable(arg, op->size); - } - break; + rv = flask_disable(); + break; case FLASK_GETAVC_THRESHOLD: - { - length = snprintf(arg, op->size, "%d", avc_cache_threshold); - } - break; + rv = avc_cache_threshold; + break; case FLASK_SETAVC_THRESHOLD: - { - length = flask_security_setavc_threshold(arg, op->size); - } - break; + rv = flask_security_setavc_threshold(&op.u.setavc_threshold); + break; case FLASK_AVC_HASHSTATS: - { - length = avc_get_hash_stats(arg, op->size); - } - break; + rv = avc_get_hash_stats(&op.u.hash_stats); + break; -#ifdef FLASK_AVC_STATS +#ifdef FLASK_AVC_STATS case FLASK_AVC_CACHESTATS: - { - length = flask_security_avc_cachestats(arg, op->size); - } - break; + rv = flask_security_avc_cachestats(&op.u.cache_stats); + break; #endif case FLASK_MEMBER: - { - length = flask_security_member(arg, op->size); - } - break; + rv = flask_security_member(&op.u.transition); + break; case FLASK_ADD_OCONTEXT: - { - length = flask_ocontext_add(arg, op->size); + rv = flask_ocontext_add(&op.u.ocontext); break; - } case FLASK_DEL_OCONTEXT: - { - length = flask_ocontext_del(arg, op->size); + rv = flask_ocontext_del(&op.u.ocontext); break; - } - - case FLASK_GETBOOL_NAMED: - { - length = flask_security_get_bool_name(arg, op->size); - } - break; - - case FLASK_GETBOOL2: - { - length = flask_security_get_bool(arg, op->size, 1); - } - break; - - case FLASK_SETBOOL_NAMED: - { - length = flask_security_set_bool_name(arg, op->size); - } - break; default: - length = -ENOSYS; - break; - + rv = -ENOSYS; } - if ( length < 0 ) - { - rc = length; + if ( rv < 0 ) goto out; - } - - if ( (FLASK_COPY_OUT&(1UL<<op->cmd)) && op->buf != NULL && - copy_to_guest(guest_handle_from_ptr(op->buf, char), arg, op->size) ) + + if ( (FLASK_COPY_OUT&(1UL<<op.cmd)) ) { - rc = -EFAULT; - goto out; + if ( copy_to_guest(u_flask_op, &op, 1) ) + rv = -EFAULT; } - op->size = length; - if ( copy_to_guest(u_flask_op, op, 1) ) - rc = -EFAULT; - out: - xfree(arg); - return rc; + return rv; } diff --git a/xen/xsm/flask/include/avc.h b/xen/xsm/flask/include/avc.h index 8fffbb6..0f62891 100644 --- a/xen/xsm/flask/include/avc.h +++ b/xen/xsm/flask/include/avc.h @@ -104,7 +104,8 @@ int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid, u32 ssid, u32 tsid, u16 tclass, u32 perms); /* Exported to selinuxfs */ -int avc_get_hash_stats(char *buf, uint32_t size); +struct xen_flask_hash_stats; +int avc_get_hash_stats(struct xen_flask_hash_stats *arg); extern unsigned int avc_cache_threshold; #ifdef FLASK_AVC_STATS diff --git a/xen/xsm/flask/include/security.h b/xen/xsm/flask/include/security.h index 67ca6d0..348f018 100644 --- a/xen/xsm/flask/include/security.h +++ b/xen/xsm/flask/include/security.h @@ -90,8 +90,8 @@ int security_iterate_iomem_sids(unsigned long start, unsigned long end, int security_iterate_ioport_sids(u32 start, u32 end, security_iterate_fn fn, void *data); -int security_ocontext_add(char *ocontext, unsigned long low, +int security_ocontext_add(u32 ocontext, unsigned long low, unsigned long high, u32 sid); -int security_ocontext_del(char *ocontext, unsigned int low, unsigned int high); +int security_ocontext_del(u32 ocontext, unsigned int low, unsigned int high); #endif /* _FLASK_SECURITY_H_ */ diff --git a/xen/xsm/flask/ss/services.c b/xen/xsm/flask/ss/services.c index 0189baf..363f586 100644 --- a/xen/xsm/flask/ss/services.c +++ b/xen/xsm/flask/ss/services.c @@ -2097,17 +2097,14 @@ int determine_ocontext( char *ocontext ) return -1; } -int security_ocontext_add( char *ocontext, unsigned long low, unsigned long high +int security_ocontext_add( u32 ocon, unsigned long low, unsigned long high ,u32 sid ) { int ret = 0; - int ocon = 0; struct ocontext *c; struct ocontext *prev; struct ocontext *add; - if ( (ocon = determine_ocontext(ocontext)) < 0 ) - return -EINVAL; if ( (add = xmalloc(struct ocontext)) == NULL ) return -ENOMEM; memset(add, 0, sizeof(struct ocontext)); @@ -2254,15 +2251,11 @@ int security_ocontext_add( char *ocontext, unsigned long low, unsigned long high return ret; } -int security_ocontext_del( char *ocontext, unsigned int low, unsigned int high ) +int security_ocontext_del( u32 ocon, unsigned int low, unsigned int high ) { int ret = 0; - int ocon = 0; struct ocontext *c, *before_c; - if ( (ocon = determine_ocontext(ocontext)) < 0 ) - return -EINVAL; - POLICY_WRLOCK; switch( ocon ) { -- 1.7.7.6
Daniel De Graaf
2012-Feb-03 15:13 UTC
[PATCH 4/4] xen: Remove unused vsscanf/sscanf functions
Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- xen/common/vsprintf.c | 236 ------------------------------------------------- xen/include/xen/lib.h | 4 - 2 files changed, 0 insertions(+), 240 deletions(-) diff --git a/xen/common/vsprintf.c b/xen/common/vsprintf.c index d9128e1..00a6e09 100644 --- a/xen/common/vsprintf.c +++ b/xen/common/vsprintf.c @@ -512,223 +512,6 @@ int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) EXPORT_SYMBOL(vscnprintf); /** - * vsscanf - Unformat a buffer into a list of arguments - * @buf: input buffer - * @fmt: format of buffer - * @args: arguments - */ -int vsscanf(const char * buf, const char * fmt, va_list args) -{ - const char *str = buf; - const char *next; - char digit; - int num = 0; - int qualifier; - int base; - int field_width; - int is_sign = 0; - - while (*fmt && *str) { - /* skip any white space in format */ - /* white space in format matchs any amount of - * white space, including none, in the input. - */ - if (isspace(*fmt)) { - while (isspace(*fmt)) - ++fmt; - while (isspace(*str)) - ++str; - } - - /* anything that is not a conversion must match exactly */ - if (*fmt != ''%'' && *fmt) { - if (*fmt++ != *str++) - break; - continue; - } - - if (!*fmt) - break; - ++fmt; - - /* skip this conversion. - * advance both strings to next white space - */ - if (*fmt == ''*'') { - while (!isspace(*fmt) && *fmt) - fmt++; - while (!isspace(*str) && *str) - str++; - continue; - } - - /* get field width */ - field_width = -1; - if (isdigit(*fmt)) - field_width = skip_atoi(&fmt); - - /* get conversion qualifier */ - qualifier = -1; - if (*fmt == ''h'' || *fmt == ''l'' || *fmt == ''L'' || *fmt == ''Z'' - || *fmt == ''z'') { - qualifier = *fmt++; - if (unlikely(qualifier == *fmt)) { - if (qualifier == ''h'') { - qualifier = ''H''; - fmt++; - } else if (qualifier == ''l'') { - qualifier = ''L''; - fmt++; - } - } - } - base = 10; - is_sign = 0; - - if (!*fmt || !*str) - break; - - switch(*fmt++) { - case ''c'': { - char *s = (char *) va_arg(args,char*); - if (field_width == -1) - field_width = 1; - do { - *s++ = *str++; - } while (--field_width > 0 && *str); - num++; - } - continue; - case ''s'': { - char *s = (char *) va_arg(args, char *); - if(field_width == -1) - field_width = INT_MAX; - /* first, skip leading white space in buffer */ - while (isspace(*str)) - str++; - - /* now copy until next white space */ - while (*str && !isspace(*str) && field_width--) - *s++ = *str++; - *s = ''\0''; - num++; - } - continue; - case ''n'': { - /* return number of characters read so far */ - int *i = (int *)va_arg(args,int*); - *i = str - buf; - } - continue; - case ''o'': - base = 8; - break; - case ''x'': - case ''X'': - base = 16; - break; - case ''i'': - base = 0; - case ''d'': - is_sign = 1; - case ''u'': - break; - case ''%'': - /* looking for ''%'' in str */ - if (*str++ != ''%'') - return num; - continue; - default: - /* invalid format; stop here */ - return num; - } - - /* have some sort of integer conversion. - * first, skip white space in buffer. - */ - while (isspace(*str)) - str++; - - digit = *str; - if (is_sign && digit == ''-'') - digit = *(str + 1); - - if (!digit || (base == 16 && !isxdigit(digit)) - || (base == 10 && !isdigit(digit)) - || (base == 8 && (!isdigit(digit) || digit > ''7'')) - || (base == 0 && !isdigit(digit))) - break; - - switch(qualifier) { - case ''H'': /* that''s ''hh'' in format */ - if (is_sign) { - signed char *s = (signed char *) va_arg(args,signed char *); - *s = (signed char) simple_strtol(str,&next,base); - } else { - unsigned char *s = (unsigned char *) - va_arg(args, unsigned char *); - *s = (unsigned char) simple_strtoul(str, &next, base); - } - break; - case ''h'': - if (is_sign) { - short *s = (short *) va_arg(args,short *); - *s = (short) simple_strtol(str,&next,base); - } else { - unsigned short *s = (unsigned short *) - va_arg(args, unsigned short *); - *s = (unsigned short) simple_strtoul(str, &next, base); - } - break; - case ''l'': - if (is_sign) { - long *l = (long *) va_arg(args,long *); - *l = simple_strtol(str,&next,base); - } else { - unsigned long *l = (unsigned long*) - va_arg(args,unsigned long*); - *l = simple_strtoul(str,&next,base); - } - break; - case ''L'': - if (is_sign) { - long long *l = (long long*) va_arg(args,long long *); - *l = simple_strtoll(str,&next,base); - } else { - unsigned long long *l = (unsigned long long*) - va_arg(args,unsigned long long*); - *l = simple_strtoull(str,&next,base); - } - break; - case ''Z'': - case ''z'': { - size_t *s = (size_t*) va_arg(args,size_t*); - *s = (size_t) simple_strtoul(str,&next,base); - } - break; - default: - if (is_sign) { - int *i = (int *) va_arg(args, int*); - *i = (int) simple_strtol(str,&next,base); - } else { - unsigned int *i = (unsigned int*) - va_arg(args, unsigned int*); - *i = (unsigned int) simple_strtoul(str,&next,base); - } - break; - } - num++; - - if (!next) - break; - str = next; - } - return num; -} - -EXPORT_SYMBOL(vsscanf); - -/** * snprintf - Format a string and place it in a buffer * @buf: The buffer to place the result into * @size: The size of the buffer, including the trailing null space @@ -779,25 +562,6 @@ int scnprintf(char * buf, size_t size, const char *fmt, ...) } EXPORT_SYMBOL(scnprintf); -/** - * sscanf - Unformat a buffer into a list of arguments - * @buf: input buffer - * @fmt: formatting of buffer - * @...: resulting arguments - */ -int sscanf(const char * buf, const char * fmt, ...) -{ - va_list args; - int i; - - va_start(args,fmt); - i = vsscanf(buf,fmt,args); - va_end(args); - return i; -} - -EXPORT_SYMBOL(sscanf); - /* * Local variables: * mode: C diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h index c8cd9fc..d6f9182 100644 --- a/xen/include/xen/lib.h +++ b/xen/include/xen/lib.h @@ -89,10 +89,6 @@ extern int scnprintf(char * buf, size_t size, const char * fmt, ...) __attribute__ ((format (printf, 3, 4))); extern int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) __attribute__ ((format (printf, 3, 0))); -extern int sscanf(const char * buf, const char * fmt, ...) - __attribute__ ((format (scanf, 2, 3))); -extern int vsscanf(const char * buf, const char * fmt, va_list args) - __attribute__ ((format (scanf, 2, 0))); long simple_strtol( const char *cp,const char **endp, unsigned int base); -- 1.7.7.6
On Fri, Feb 03, Daniel De Graaf wrote:> This library has been deprecated since July 2010; remove the in-tree > users and library.> - ln -sf libflask.so.$(MAJOR) $(DESTDIR)$(LIBDIR)/libflask.so> +++ b/tools/python/setup.py > @@ -48,7 +48,7 @@ flask = Extension("flask", > include_dirs = [ PATH_XEN, PATH_LIBXC, "xen/lowlevel/flask", > "../flask/libflask/include" ], > library_dirs = [ PATH_LIBXC, "../flask/libflask" ], > - libraries = [ "xenctrl", "flask" ], > + libraries = [ "xenctrl" ], > depends = [ PATH_LIBXC + "/libxenctrl.so", > XEN_ROOT + "/tools/flask/libflask/libflask.so" ], > sources = [ "xen/lowlevel/flask/flask.c" ])For some reason this changeset does not cause buildfailures in automated testing. My xen-unstable rpm packages fail to build in SLES11, but not in openSuSE for some reason. Is there a chance that libflask.so is built after this python thing runs? In other words: Is there a makefile dependency missing? Olaf ... building ''flask'' extension error: ../../tools/flask/libflask/libflask.so: No such file or directory make[3]: *** [install] Error 1 make[3]: Leaving directory `/usr/src/packages/BUILD/xen-4.2.24701/non-dbg/tools/python'' make[2]: *** [subdir-install-python] Error 2 ...
On Tue, Feb 07, Olaf Hering wrote: After poking at this some more, isnt the patch removing the libflask directory? I think it should have removed also all references to that directory. setup.py (or python 2.6) in SLES11 can not cope with it, while python 2.7 in openSuSE seems to ignore the remove directory. I will send a tested patch which removes the references to libflask. Olaf> On Fri, Feb 03, Daniel De Graaf wrote: > > > This library has been deprecated since July 2010; remove the in-tree > > users and library. > > > - ln -sf libflask.so.$(MAJOR) $(DESTDIR)$(LIBDIR)/libflask.so > > > +++ b/tools/python/setup.py > > @@ -48,7 +48,7 @@ flask = Extension("flask", > > include_dirs = [ PATH_XEN, PATH_LIBXC, "xen/lowlevel/flask", > > "../flask/libflask/include" ], > > library_dirs = [ PATH_LIBXC, "../flask/libflask" ], > > - libraries = [ "xenctrl", "flask" ], > > + libraries = [ "xenctrl" ], > > depends = [ PATH_LIBXC + "/libxenctrl.so", > > XEN_ROOT + "/tools/flask/libflask/libflask.so" ], > > sources = [ "xen/lowlevel/flask/flask.c" ]) > > > For some reason this changeset does not cause buildfailures in automated > testing. My xen-unstable rpm packages fail to build in SLES11, but not in > openSuSE for some reason. > > Is there a chance that libflask.so is built after this python thing runs? > In other words: Is there a makefile dependency missing? > > Olaf > > ... > building ''flask'' extension > error: ../../tools/flask/libflask/libflask.so: No such file or directory > make[3]: *** [install] Error 1 > make[3]: Leaving directory `/usr/src/packages/BUILD/xen-4.2.24701/non-dbg/tools/python'' > make[2]: *** [subdir-install-python] Error 2 > ... > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > lists.xensource.com/xen-devel >