[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/8] xsm/flask: allow policy booleans to be addressed by name
Booleans are currently only addressable by using a sequence number that is not easily accessible to tools. Add new FLASK operations to get/set booleans by name, and to get the name of a boolean given its ID. Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx> --- xen/include/public/xsm/flask_op.h | 5 +- xen/xsm/flask/flask_op.c | 159 ++++++++++++++++++++++++++++++----- xen/xsm/flask/include/conditional.h | 5 +- xen/xsm/flask/ss/services.c | 75 +++++++++++++---- 4 files changed, 207 insertions(+), 37 deletions(-) diff --git a/xen/include/public/xsm/flask_op.h b/xen/include/public/xsm/flask_op.h index e2dd403..416ac08 100644 --- a/xen/include/public/xsm/flask_op.h +++ b/xen/include/public/xsm/flask_op.h @@ -47,8 +47,11 @@ #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_DEL_OCONTEXT +#define FLASK_LAST FLASK_SETBOOL_NAMED typedef struct flask_op { uint32_t cmd; diff --git a/xen/xsm/flask/flask_op.c b/xen/xsm/flask/flask_op.c index 265a3cf..64d9ec5 100644 --- a/xen/xsm/flask/flask_op.c +++ b/xen/xsm/flask/flask_op.c @@ -47,7 +47,10 @@ integer_param("flask_enabled", flask_enabled); 1UL<<FLASK_SETAVC_THRESHOLD | \ 1UL<<FLASK_MEMBER | \ 1UL<<FLASK_ADD_OCONTEXT | \ - 1UL<<FLASK_DEL_OCONTEXT \ + 1UL<<FLASK_DEL_OCONTEXT | \ + 1UL<<FLASK_GETBOOL_NAMED | \ + 1UL<<FLASK_GETBOOL2 | \ + 1UL<<FLASK_SETBOOL_NAMED \ ) #define FLASK_COPY_OUT \ @@ -65,7 +68,9 @@ integer_param("flask_enabled", flask_enabled); 1UL<<FLASK_GETAVC_THRESHOLD | \ 1UL<<FLASK_AVC_HASHSTATS | \ 1UL<<FLASK_AVC_CACHESTATS | \ - 1UL<<FLASK_MEMBER \ + 1UL<<FLASK_MEMBER | \ + 1UL<<FLASK_GETBOOL_NAMED | \ + 1UL<<FLASK_GETBOOL2 \ ) static DEFINE_SPINLOCK(sel_sem); @@ -73,6 +78,7 @@ static DEFINE_SPINLOCK(sel_sem); /* global data for booleans */ static int bool_num = 0; static int *bool_pending_values = NULL; +static int flask_security_make_bools(void); extern int ss_initialized; @@ -573,7 +579,7 @@ static int flask_security_setavc_threshold(char *buf, uint32_t count) static int flask_security_set_bool(char *buf, uint32_t count) { int length = -EFAULT; - int i, new_value; + unsigned int i, new_value; spin_lock(&sel_sem); @@ -585,10 +591,14 @@ static int flask_security_set_bool(char *buf, uint32_t count) if ( sscanf(buf, "%d %d", &i, &new_value) != 2 ) goto out; + if (!bool_pending_values) + flask_security_make_bools(); + + if ( i >= bool_num ) + goto out; + if ( new_value ) - { new_value = 1; - } bool_pending_values[i] = new_value; length = count; @@ -598,6 +608,57 @@ static int flask_security_set_bool(char *buf, uint32_t count) return length; } +static int flask_security_set_bool_name(char *buf, uint32_t count) +{ + int rv, num; + int i, new_value, commit; + int *values = NULL; + char *name; + + name = xmalloc_bytes(count); + if ( name == NULL ) + return -ENOMEM; + + spin_lock(&sel_sem); + + 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; + + i = security_find_bool(name); + if ( i < 0 ) + goto out; + + if ( new_value ) + new_value = 1; + + 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; + rv = security_set_bools(num, values); + xfree(values); + } else { + if (!bool_pending_values) + flask_security_make_bools(); + + bool_pending_values[i] = new_value; + rv = count; + } + + out: + xfree(name); + spin_unlock(&sel_sem); + return rv; +} + static int flask_security_commit_bools(char *buf, uint32_t count) { int length = -EFAULT; @@ -613,7 +674,7 @@ static int flask_security_commit_bools(char *buf, uint32_t count) if ( sscanf(buf, "%d", &new_value) != 1 ) goto out; - if ( new_value ) + if ( new_value && bool_pending_values ) security_set_bools(bool_num, bool_pending_values); length = count; @@ -623,10 +684,11 @@ static int flask_security_commit_bools(char *buf, uint32_t count) return length; } -static int flask_security_get_bool(char *buf, uint32_t count) +static int flask_security_get_bool(char *buf, uint32_t count, int named) { int length; - int i, cur_enforcing; + int i, cur_enforcing, pend_enforcing; + char* name = NULL; spin_lock(&sel_sem); @@ -641,25 +703,70 @@ static int flask_security_get_bool(char *buf, uint32_t count) goto out; } + if ( bool_pending_values ) + pend_enforcing = bool_pending_values[i]; + else + pend_enforcing = cur_enforcing; + + if ( named ) + name = security_get_bool_name(i); + if ( named && !name ) + goto out; + memset(buf, 0, count); - length = snprintf(buf, count, "%d %d", cur_enforcing, - bool_pending_values[i]); + 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); out: + xfree(name); spin_unlock(&sel_sem); return length; } +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; + + cur_enforcing = security_get_bool_value(i); + if ( cur_enforcing < 0 ) + { + rv = cur_enforcing; + goto out; + } + + 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; +} + static int flask_security_make_bools(void) { - int i, ret = 0; - char **names = NULL; + int ret = 0; int num; int *values = NULL; xfree(bool_pending_values); - ret = security_get_bools(&num, &names, &values); + ret = security_get_bools(&num, NULL, &values); if ( ret != 0 ) goto out; @@ -667,12 +774,6 @@ static int flask_security_make_bools(void) bool_pending_values = values; out: - if ( names ) - { - for ( i = 0; i < num; i++ ) - xfree(names[i]); - xfree(names); - } return ret; } @@ -938,7 +1039,7 @@ long do_flask_op(XEN_GUEST_HANDLE(xsm_op_t) u_flask_op) case FLASK_GETBOOL: { - length = flask_security_get_bool(arg, op->size); + length = flask_security_get_bool(arg, op->size, 0); } break; @@ -1010,6 +1111,24 @@ long do_flask_op(XEN_GUEST_HANDLE(xsm_op_t) u_flask_op) 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; diff --git a/xen/xsm/flask/include/conditional.h b/xen/xsm/flask/include/conditional.h index bd3eb92..2fa0a30 100644 --- a/xen/xsm/flask/include/conditional.h +++ b/xen/xsm/flask/include/conditional.h @@ -17,6 +17,9 @@ int security_get_bools(int *len, char ***names, int **values); int security_set_bools(int len, int *values); -int security_get_bool_value(int bool); +int security_find_bool(const char *name); + +char *security_get_bool_name(unsigned int bool); +int security_get_bool_value(unsigned int bool); #endif diff --git a/xen/xsm/flask/ss/services.c b/xen/xsm/flask/ss/services.c index 3b0acf5..0189baf 100644 --- a/xen/xsm/flask/ss/services.c +++ b/xen/xsm/flask/ss/services.c @@ -1883,12 +1883,30 @@ out: return rc; } +int security_find_bool(const char *name) +{ + int i, rv = -ENOENT; + POLICY_RDLOCK; + for ( i = 0; i < policydb.p_bools.nprim; i++ ) + { + if (!strcmp(name, policydb.p_bool_val_to_name[i])) + { + rv = i; + break; + } + } + + POLICY_RDUNLOCK; + return rv; +} + int security_get_bools(int *len, char ***names, int **values) { int i, rc = -ENOMEM; POLICY_RDLOCK; - *names = NULL; + if ( names ) + *names = NULL; *values = NULL; *len = policydb.p_bools.nprim; @@ -1898,10 +1916,12 @@ int security_get_bools(int *len, char ***names, int **values) goto out; } - *names = (char**)xmalloc_array(char*, *len); - if ( !*names ) - goto err; - memset(*names, 0, sizeof(char*) * *len); + if ( names ) { + *names = (char**)xmalloc_array(char*, *len); + if ( !*names ) + goto err; + memset(*names, 0, sizeof(char*) * *len); + } *values = (int*)xmalloc_array(int, *len); if ( !*values ) @@ -1911,19 +1931,21 @@ int security_get_bools(int *len, char ***names, int **values) { size_t name_len; (*values)[i] = policydb.bool_val_to_struct[i]->state; - name_len = strlen(policydb.p_bool_val_to_name[i]) + 1; - (*names)[i] = (char*)xmalloc_array(char, name_len); - if ( !(*names)[i] ) - goto err; - strlcpy((*names)[i], policydb.p_bool_val_to_name[i], name_len); - (*names)[i][name_len - 1] = 0; + if ( names ) { + name_len = strlen(policydb.p_bool_val_to_name[i]) + 1; + (*names)[i] = (char*)xmalloc_array(char, name_len); + if ( !(*names)[i] ) + goto err; + strlcpy((*names)[i], policydb.p_bool_val_to_name[i], name_len); + (*names)[i][name_len - 1] = 0; + } } rc = 0; out: POLICY_RDUNLOCK; return rc; err: - if ( *names ) + if ( names && *names ) { for ( i = 0; i < *len; i++ ) xfree((*names)[i]); @@ -1984,17 +2006,17 @@ out: return rc; } -int security_get_bool_value(int bool) +int security_get_bool_value(unsigned int bool) { int rc = 0; - int len; + unsigned int len; POLICY_RDLOCK; len = policydb.p_bools.nprim; if ( bool >= len ) { - rc = -EFAULT; + rc = -ENOENT; goto out; } @@ -2004,6 +2026,29 @@ out: return rc; } +char *security_get_bool_name(unsigned int bool) +{ + unsigned int len; + char *rv = NULL; + + POLICY_RDLOCK; + + len = policydb.p_bools.nprim; + if ( bool >= len ) + { + goto out; + } + + len = strlen(policydb.p_bool_val_to_name[bool]) + 1; + rv = xmalloc_array(char, len); + if ( !rv ) + goto out; + memcpy(rv, policydb.p_bool_val_to_name[bool], len); +out: + POLICY_RDUNLOCK; + return rv; +} + static int security_preserve_bools(struct policydb *p) { int rc, nbools = 0, *bvalues = NULL, i; -- 1.7.7.6 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |