debuggers.hg

changeset 20895:23a2ae169779

tools/xsm: Expose Flask XSM AVC functions to user-space

This patch exposes the flask_access, flask_avc_cachestats,
flask_avc_hashstats, flask_getavc_threshold, flask_setavc_threshold,
and flask_policyvers functions to user-space. A python wrapper was
created for the flask_access function to facilitate policy based
user-space access control decisions. flask.h was renamed to libflask.h
to remove a naming conflict.

Signed-off-by : Machon Gregory <mbgrego@tycho.ncsc.mil>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jan 26 07:50:04 2010 +0000 (2010-01-26)
parents cd453b3d7b25
children 9ec971345d9f
files tools/flask/libflask/Makefile tools/flask/libflask/flask_op.c tools/flask/libflask/include/flask.h tools/flask/libflask/include/libflask.h tools/flask/utils/getenforce.c tools/flask/utils/loadpolicy.c tools/flask/utils/setenforce.c tools/python/xen/lowlevel/flask/flask.c
line diff
     1.1 --- a/tools/flask/libflask/Makefile	Sat Jan 23 08:28:01 2010 +0000
     1.2 +++ b/tools/flask/libflask/Makefile	Tue Jan 26 07:50:04 2010 +0000
     1.3 @@ -38,7 +38,7 @@ install: build
     1.4  	$(INSTALL_DATA) libflask.a $(DESTDIR)$(LIBDIR)
     1.5  	ln -sf libflask.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)/libflask.so.$(MAJOR)
     1.6  	ln -sf libflask.so.$(MAJOR) $(DESTDIR)$(LIBDIR)/libflask.so
     1.7 -	$(INSTALL_DATA) include/flask.h $(DESTDIR)$(INCLUDEDIR)
     1.8 +	$(INSTALL_DATA) include/libflask.h $(DESTDIR)$(INCLUDEDIR)/xen/xsm
     1.9  
    1.10  .PHONY: TAGS
    1.11  TAGS:
     2.1 --- a/tools/flask/libflask/flask_op.c	Sat Jan 23 08:28:01 2010 +0000
     2.2 +++ b/tools/flask/libflask/flask_op.c	Tue Jan 26 07:50:04 2010 +0000
     2.3 @@ -19,7 +19,7 @@
     2.4  #include <stdlib.h>
     2.5  #include <stdint.h>
     2.6  #include <sys/ioctl.h>
     2.7 -#include <flask.h>
     2.8 +#include <libflask.h>
     2.9  #include <xenctrl.h>
    2.10  
    2.11  int flask_load(int xc_handle, char *buf, uint32_t size)
    2.12 @@ -342,3 +342,160 @@ int flask_del_device(int xc_handle, unsi
    2.13      return 0;
    2.14  
    2.15  }
    2.16 +
    2.17 +int flask_access(int xc_handle, const char *scon, const char *tcon,
    2.18 +                u_int16_t tclass, u_int32_t req,
    2.19 +                u_int32_t *allowed, u_int32_t *decided,
    2.20 +                u_int32_t *auditallow, u_int32_t *auditdeny,
    2.21 +                u_int32_t *seqno)
    2.22 +{
    2.23 +/* maximum number of digits in a 16-bit decimal number: */
    2.24 +#define MAX_SHORT_DEC_LEN 5
    2.25 +
    2.26 +    char *buf;
    2.27 +    int bufLen;
    2.28 +    int err;
    2.29 +    flask_op_t op;
    2.30 +    u_int32_t dummy_allowed;
    2.31 +    u_int32_t dummy_decided;
    2.32 +    u_int32_t dummy_auditallow;
    2.33 +    u_int32_t dummy_auditdeny;
    2.34 +    u_int32_t dummy_seqno;
    2.35 +  
    2.36 +    if (!allowed)
    2.37 +        allowed = &dummy_allowed;
    2.38 +    if (!decided)
    2.39 +        decided = &dummy_decided;
    2.40 +    if (!auditallow)
    2.41 +        auditallow = &dummy_auditallow;
    2.42 +    if (!auditdeny)
    2.43 +        auditdeny = &dummy_auditdeny;
    2.44 +    if (!seqno)
    2.45 +        seqno = &dummy_seqno;
    2.46 +
    2.47 +    if (!scon)
    2.48 +        return -EINVAL;
    2.49 +    if (!tcon)
    2.50 +        return -EINVAL;
    2.51 +
    2.52 +    bufLen = strlen(scon) + 1 + strlen(tcon) + 1 +
    2.53 +        MAX_SHORT_DEC_LEN + 1 +
    2.54 +        sizeof(req)*2 + 1;
    2.55 +    buf = malloc(bufLen);
    2.56 +    snprintf(buf, bufLen, "%s %s %hu %x", scon, tcon, tclass, req);
    2.57 +
    2.58 +    op.cmd = FLASK_ACCESS;
    2.59 +    op.buf = buf;
    2.60 +    op.size = strlen(buf)+1;
    2.61 +    
    2.62 +    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
    2.63 +    {
    2.64 +        free(buf);
    2.65 +        return err;
    2.66 +    }
    2.67 +   
    2.68 +    if (sscanf(op.buf, "%x %x %x %x %u",
    2.69 +               allowed, decided,
    2.70 +               auditallow, auditdeny,
    2.71 +               seqno) != 5) {
    2.72 +        err = -EILSEQ;
    2.73 +    }
    2.74 +
    2.75 +    err = ((*allowed & req) == req)? 0 : -EPERM;
    2.76 +
    2.77 +    return err;
    2.78 +
    2.79 +}
    2.80 +
    2.81 +int flask_avc_hashstats(int xc_handle, char *buf, int size)
    2.82 +{
    2.83 +    int err;
    2.84 +    flask_op_t op;
    2.85 +  
    2.86 +    op.cmd = FLASK_AVC_HASHSTATS;
    2.87 +    op.buf = buf;
    2.88 +    op.size = size;
    2.89 +  
    2.90 +    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
    2.91 +    {
    2.92 +        free(buf);
    2.93 +        return err;
    2.94 +    }
    2.95 +
    2.96 +    return 0;
    2.97 +}
    2.98 +
    2.99 +int flask_avc_cachestats(int xc_handle, char *buf, int size)
   2.100 +{
   2.101 +    int err;
   2.102 +    flask_op_t op;
   2.103 +  
   2.104 +    op.cmd = FLASK_AVC_CACHESTATS;
   2.105 +    op.buf = buf;
   2.106 +    op.size = size;
   2.107 +  
   2.108 +    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
   2.109 +    {
   2.110 +        free(buf);
   2.111 +        return err;
   2.112 +    }
   2.113 +
   2.114 +    return 0;
   2.115 +}
   2.116 +
   2.117 +int flask_policyvers(int xc_handle, char *buf, int size)
   2.118 +{
   2.119 +    int err;
   2.120 +    flask_op_t op;
   2.121 +  
   2.122 +    op.cmd = FLASK_POLICYVERS;
   2.123 +    op.buf = buf;
   2.124 +    op.size = size;
   2.125 +
   2.126 +    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
   2.127 +    {
   2.128 +        free(buf);
   2.129 +        return err;
   2.130 +    }
   2.131 +
   2.132 +    return 0;
   2.133 +}
   2.134 +
   2.135 +int flask_getavc_threshold(int xc_handle)
   2.136 +{
   2.137 +    int err;
   2.138 +    flask_op_t op;
   2.139 +    char buf[20];            
   2.140 +    int size = 20;
   2.141 +    int threshold;
   2.142 + 
   2.143 +    op.cmd = FLASK_GETAVC_THRESHOLD;
   2.144 +    op.buf = buf;
   2.145 +    op.size = size;
   2.146 +    
   2.147 +    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
   2.148 +        return err;
   2.149 +
   2.150 +    sscanf(buf, "%i", &threshold);
   2.151 +
   2.152 +    return threshold;
   2.153 +}
   2.154 +
   2.155 +int flask_setavc_threshold(int xc_handle, int threshold)
   2.156 +{
   2.157 +    int err;
   2.158 +    flask_op_t op;
   2.159 +    char buf[20];            
   2.160 +    int size = 20;
   2.161 + 
   2.162 +    op.cmd = FLASK_SETAVC_THRESHOLD;
   2.163 +    op.buf = buf;
   2.164 +    op.size = size;
   2.165 +
   2.166 +    snprintf(buf, size, "%i", threshold);
   2.167 + 
   2.168 +    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
   2.169 +        return err;
   2.170 +
   2.171 +    return 0;
   2.172 +}
     3.1 --- a/tools/flask/libflask/include/flask.h	Sat Jan 23 08:28:01 2010 +0000
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,43 +0,0 @@
     3.4 -/*
     3.5 - *
     3.6 - *  Authors:  Michael LeMay, <mdlemay@epoch.ncsc.mil>
     3.7 - *            George Coker, <gscoker@alpha.ncsc.mil>
     3.8 - *
     3.9 - *  This program is free software; you can redistribute it and/or modify
    3.10 - *  it under the terms of the GNU General Public License version 2,
    3.11 - *  as published by the Free Software Foundation.
    3.12 - */
    3.13 -
    3.14 -#ifndef __FLASK_H__
    3.15 -#define __FLASK_H__
    3.16 -
    3.17 -#include <stdint.h>
    3.18 -#include <xen/xen.h>
    3.19 -#include <xen/xsm/flask_op.h>
    3.20 -
    3.21 -int flask_load(int xc_handle, char *buf, uint32_t size);
    3.22 -int flask_context_to_sid(int xc_handle, char *buf, uint32_t size, uint32_t *sid);
    3.23 -int flask_sid_to_context(int xc_handle, int sid, char *buf, uint32_t size);
    3.24 -int flask_getenforce(int xc_handle);
    3.25 -int flask_setenforce(int xc_handle, int mode);
    3.26 -int flask_add_pirq(int xc_handle, unsigned int pirq, char *scontext);
    3.27 -int flask_add_ioport(int xc_handle, unsigned long low, unsigned long high,
    3.28 -                      char *scontext);
    3.29 -int flask_add_iomem(int xc_handle, unsigned long low, unsigned long high,
    3.30 -                     char *scontext);
    3.31 -int flask_add_device(int xc_handle, unsigned long device, char *scontext);
    3.32 -int flask_del_pirq(int xc_handle, unsigned int pirq);
    3.33 -int flask_del_ioport(int xc_handle, unsigned long low, unsigned long high);
    3.34 -int flask_del_iomem(int xc_handle, unsigned long low, unsigned long high);
    3.35 -int flask_del_device(int xc_handle, unsigned long device);
    3.36 -#define flask_add_single_ioport(x, l, s) flask_add_ioport(x, l, l, s)
    3.37 -#define flask_add_single_iomem(x, l, s) flask_add_iomem(x, l, l, s)
    3.38 -#define flask_del_single_ioport(x, l) flask_del_ioport(x, l, l)
    3.39 -#define flask_del_single_iomem(x, l) flask_del_iomem(x, l, l);
    3.40 -
    3.41 -#define OCON_PIRQ_STR   "pirq"
    3.42 -#define OCON_IOPORT_STR "ioport"
    3.43 -#define OCON_IOMEM_STR  "iomem"
    3.44 -#define OCON_DEVICE_STR "pcidevice"
    3.45 -#define INITCONTEXTLEN  256
    3.46 -#endif /* __FLASK_H__ */
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/flask/libflask/include/libflask.h	Tue Jan 26 07:50:04 2010 +0000
     4.3 @@ -0,0 +1,53 @@
     4.4 +/*
     4.5 + *
     4.6 + *  Authors:  Michael LeMay, <mdlemay@epoch.ncsc.mil>
     4.7 + *            George Coker, <gscoker@alpha.ncsc.mil>
     4.8 + *
     4.9 + *  This program is free software; you can redistribute it and/or modify
    4.10 + *  it under the terms of the GNU General Public License version 2,
    4.11 + *  as published by the Free Software Foundation.
    4.12 + */
    4.13 +
    4.14 +#ifndef __LIBFLASK_H__
    4.15 +#define __LIBFLASK_H__
    4.16 +
    4.17 +#include <stdint.h>
    4.18 +#include <xen/xen.h>
    4.19 +#include <xen/xsm/flask_op.h>
    4.20 +
    4.21 +int flask_load(int xc_handle, char *buf, uint32_t size);
    4.22 +int flask_context_to_sid(int xc_handle, char *buf, uint32_t size, uint32_t *sid);
    4.23 +int flask_sid_to_context(int xc_handle, int sid, char *buf, uint32_t size);
    4.24 +int flask_getenforce(int xc_handle);
    4.25 +int flask_setenforce(int xc_handle, int mode);
    4.26 +int flask_add_pirq(int xc_handle, unsigned int pirq, char *scontext);
    4.27 +int flask_add_ioport(int xc_handle, unsigned long low, unsigned long high,
    4.28 +                      char *scontext);
    4.29 +int flask_add_iomem(int xc_handle, unsigned long low, unsigned long high,
    4.30 +                     char *scontext);
    4.31 +int flask_add_device(int xc_handle, unsigned long device, char *scontext);
    4.32 +int flask_del_pirq(int xc_handle, unsigned int pirq);
    4.33 +int flask_del_ioport(int xc_handle, unsigned long low, unsigned long high);
    4.34 +int flask_del_iomem(int xc_handle, unsigned long low, unsigned long high);
    4.35 +int flask_del_device(int xc_handle, unsigned long device);
    4.36 +int flask_access(int xc_handle, const char *scon, const char *tcon,
    4.37 +                  u_int16_t tclass, u_int32_t req,
    4.38 +                  u_int32_t *allowed, u_int32_t *decided,
    4.39 +                  u_int32_t *auditallow, u_int32_t *auditdeny,
    4.40 +                  u_int32_t *seqno);
    4.41 +int flask_avc_cachestats(int xc_handle, char *buf, int size);
    4.42 +int flask_policyvers(int xc_handle, char *buf, int size);
    4.43 +int flask_avc_hashstats(int xc_handle, char *buf, int size);
    4.44 +int flask_getavc_threshold(int xc_handle);
    4.45 +int flask_setavc_threshold(int xc_handle, int threshold);
    4.46 +#define flask_add_single_ioport(x, l, s) flask_add_ioport(x, l, l, s)
    4.47 +#define flask_add_single_iomem(x, l, s) flask_add_iomem(x, l, l, s)
    4.48 +#define flask_del_single_ioport(x, l) flask_del_ioport(x, l, l)
    4.49 +#define flask_del_single_iomem(x, l) flask_del_iomem(x, l, l);
    4.50 +
    4.51 +#define OCON_PIRQ_STR   "pirq"
    4.52 +#define OCON_IOPORT_STR "ioport"
    4.53 +#define OCON_IOMEM_STR  "iomem"
    4.54 +#define OCON_DEVICE_STR "pcidevice"
    4.55 +#define INITCONTEXTLEN  256
    4.56 +#endif /* __LIBFLASK_H__ */
     5.1 --- a/tools/flask/utils/getenforce.c	Sat Jan 23 08:28:01 2010 +0000
     5.2 +++ b/tools/flask/utils/getenforce.c	Tue Jan 26 07:50:04 2010 +0000
     5.3 @@ -16,7 +16,7 @@
     5.4  #include <sys/stat.h>
     5.5  #include <string.h>
     5.6  #include <unistd.h>
     5.7 -#include <flask.h>
     5.8 +#include <libflask.h>
     5.9  
    5.10  static void usage (int argCnt, const char *args[])
    5.11  {
     6.1 --- a/tools/flask/utils/loadpolicy.c	Sat Jan 23 08:28:01 2010 +0000
     6.2 +++ b/tools/flask/utils/loadpolicy.c	Tue Jan 26 07:50:04 2010 +0000
     6.3 @@ -17,7 +17,7 @@
     6.4  #include <sys/stat.h>
     6.5  #include <string.h>
     6.6  #include <unistd.h>
     6.7 -#include <flask.h>
     6.8 +#include <libflask.h>
     6.9  
    6.10  #define USE_MMAP
    6.11  
     7.1 --- a/tools/flask/utils/setenforce.c	Sat Jan 23 08:28:01 2010 +0000
     7.2 +++ b/tools/flask/utils/setenforce.c	Tue Jan 26 07:50:04 2010 +0000
     7.3 @@ -16,7 +16,7 @@
     7.4  #include <sys/stat.h>
     7.5  #include <string.h>
     7.6  #include <unistd.h>
     7.7 -#include <flask.h>
     7.8 +#include <libflask.h>
     7.9  
    7.10  static void usage (int argCnt, const char *args[])
    7.11  {
     8.1 --- a/tools/python/xen/lowlevel/flask/flask.c	Sat Jan 23 08:28:01 2010 +0000
     8.2 +++ b/tools/python/xen/lowlevel/flask/flask.c	Tue Jan 26 07:50:04 2010 +0000
     8.3 @@ -12,7 +12,7 @@
     8.4  
     8.5  #include <Python.h>
     8.6  #include <xenctrl.h>
     8.7 -#include <flask.h>
     8.8 +#include <libflask.h>
     8.9  
    8.10  #define PKG "xen.lowlevel.flask"
    8.11  #define CLS "flask"
    8.12 @@ -190,6 +190,44 @@ static PyObject *pyflask_setenforce(PyOb
    8.13      return Py_BuildValue("i", ret);
    8.14  }
    8.15  
    8.16 +static PyObject *pyflask_access(PyObject *self, PyObject *args,
    8.17 +                                                       PyObject *kwds)
    8.18 +{
    8.19 +    int xc_handle;
    8.20 +    char *tcon, *scon;
    8.21 +    uint16_t tclass;
    8.22 +    uint32_t req, allowed, decided, auditallow, auditdeny, seqno;
    8.23 +    int ret;
    8.24 +
    8.25 +    static char *kwd_list[] = { "src_context", "tar_context", 
    8.26 +                                "tar_class", "req_permissions",
    8.27 +                                "decided", "auditallow","auditdeny",
    8.28 +                                "seqno", NULL };
    8.29 +
    8.30 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ssil|llll", kwd_list,
    8.31 +                                      &scon, &tcon, &tclass, &req, &decided,
    8.32 +                                      &auditallow, &auditdeny, &seqno) )
    8.33 +        return NULL;
    8.34 +
    8.35 +    xc_handle = xc_interface_open();
    8.36 +    if (xc_handle < 0) {
    8.37 +        errno = xc_handle;
    8.38 +        return PyErr_SetFromErrno(xc_error_obj);
    8.39 +    }
    8.40 +    
    8.41 +    ret = flask_access(xc_handle, scon, tcon, tclass, req, &allowed, &decided,
    8.42 +                        &auditallow, &auditdeny, &seqno);
    8.43 +        
    8.44 +    xc_interface_close(xc_handle);
    8.45 +
    8.46 +    if ( ret != 0 ) {
    8.47 +        errno = -ret;
    8.48 +        return PyErr_SetFromErrno(xc_error_obj);
    8.49 +    }
    8.50 +
    8.51 +    return Py_BuildValue("i",ret);
    8.52 +}
    8.53 +
    8.54  static PyMethodDef pyflask_methods[] = {
    8.55      { "flask_context_to_sid",
    8.56        (PyCFunction)pyflask_context_to_sid,
    8.57 @@ -224,7 +262,27 @@ static PyMethodDef pyflask_methods[] = {
    8.58        "Modifies the current mode for the Flask XSM module.\n"
    8.59        " mode [int]: mode to change to\n"
    8.60        "Returns: [int]: 0 on success; -1 on failure.\n" }, 
    8.61 +
    8.62 +    { "flask_access",
    8.63 +      (PyCFunction)pyflask_access,
    8.64 +      METH_KEYWORDS, "\n"
    8.65 +      "Returns whether a source context has access to target context based on \
    8.66 +       class and permissions requested.\n"
    8.67 +      " scon [str]: source context\n"
    8.68 +      " tcon [str]: target context\n"
    8.69 +      " tclass [int]: target security class\n"
    8.70 +      " req [int] requested permissions\n"
    8.71 +      " allowed [int] permissions allow for the target class between the source \
    8.72 +        and target context\n"
    8.73 +      " decided [int] the permissions that were returned in the allowed \
    8.74 +        parameter\n"
    8.75 +      " auditallow [int] permissions set to audit on allow\n"
    8.76 +      " auditdeny [int] permissions set to audit on deny\n"
    8.77 +      " seqno [int] not used\n"
    8.78 +      "Returns: [int]: 0 on all permission granted; -1 if any permissions are \
    8.79 +       denied\n" }, 
    8.80      { NULL, NULL, 0, NULL }
    8.81 +
    8.82  };
    8.83  
    8.84  PyMODINIT_FUNC initflask(void)