Date: Mon, 7 Feb 2005 20:10:59 GMT From: Andrew Reisse <areisse@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 70542 for review Message-ID: <200502072010.j17KAxMt035588@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=70542 Change 70542 by areisse@areisse_tislabs on 2005/02/07 20:10:50 Introduce a kernel interface for reading and setting TE policy booleans (which affect the conditional rules). Affected files ... .. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/sebsd_syscall.c#6 edit .. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/sebsd_syscalls.h#6 edit .. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/conditional.c#4 edit .. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/policydb.h#7 edit .. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/security.h#8 edit .. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/services.c#9 edit Differences ... ==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/sebsd_syscall.c#6 (text+ko) ==== @@ -39,6 +39,7 @@ #include <sys/kernel.h> #include <sys/systm.h> #include <sys/malloc.h> +#include <sys/proc.h> #include <security/sebsd/sebsd.h> #include <security/sebsd/sebsd_syscalls.h> @@ -72,11 +73,26 @@ return (rc); } +static int +sebsd_get_bools(struct thread *td, struct sebsd_get_bools *gb) +{ + char *out = NULL; + if (gb->out) + out = malloc(gb->len, M_SEBSD, M_WAITOK); + int err = security_get_bool_string(&gb->len, out); + if (out && err == 0) + err = copyout(out, gb->out, gb->len); + if (out) + free(out, M_SEBSD); + return (err); +} + int sebsd_syscall(struct thread *td, int call, void *args) { int err = EINVAL; struct lp_args p; + struct sebsd_get_bools gb; switch(call) { case SEBSDCALL_LOAD_POLICY: @@ -84,6 +100,58 @@ return (EFAULT); err = sys_load_policy (td, p.data, p.len); break; + + case SEBSDCALL_GET_BOOLS: + if (copyin(args, &gb, sizeof (struct sebsd_get_bools))) + return (EFAULT); + err = sebsd_get_bools(td, &gb); + if (copyout(&gb, args, sizeof (struct sebsd_get_bools))) + return (EFAULT); + break; + + case SEBSDCALL_GET_BOOL: + { + char str[128]; + int active, pending; + err = copyinstr(args,str, 128, NULL); + if (err) + return (err); + security_get_bool(str, &active, &pending); + *td->td_retval = active | (pending << 1); + return (0); + } + + case SEBSDCALL_SET_BOOL: + { + char *str; + + err = thread_has_security(td, SECURITY__SETBOOL); + if (err) + return (err); + + if (copyin(args, &p, sizeof (struct lp_args))) + return (EFAULT); + str = malloc(p.len, M_SEBSD, M_WAITOK); + if (!str) + return (ENOMEM); + if (copyin(p.data, str, p.len)) { + free(str, M_SEBSD); + return (EFAULT); + } + + str[p.len-1] = 0; + err = security_set_bool(str+1, str[0]-'0'); + free(str, M_SEBSD); + break; + } + + case SEBSDCALL_COMMIT_BOOLS: + err = thread_has_security(td, SECURITY__SETBOOL); + if (err) + return (err); + + return security_commit_pending_bools(); + default: err = EINVAL; break; ==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/sebsd_syscalls.h#6 (text+ko) ==== @@ -7,6 +7,10 @@ * TBD: Should we really try to line up with SELinux? */ #define SEBSDCALL_LOAD_POLICY 7 +#define SEBSDCALL_GET_BOOLS 8 +#define SEBSDCALL_GET_BOOL 9 +#define SEBSDCALL_SET_BOOL 10 +#define SEBSDCALL_COMMIT_BOOLS 11 #define SEBSDCALL_NUM 7 @@ -27,6 +31,10 @@ u32 seqno; }; +struct sebsd_get_bools { + int len; + char *out; +}; #endif /* _SEBSD_SYSCALLS_H_ */ ==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/conditional.c#4 (text+ko) ==== @@ -233,6 +233,7 @@ booldatum->value = le32_to_cpu(buf[0]); booldatum->state = le32_to_cpu(buf[1]); + booldatum->pending = booldatum->state; if (!bool_isvalid(booldatum)) goto err; ==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/policydb.h#7 (text+ko) ==== @@ -121,6 +121,7 @@ struct cond_bool_datum { u32 value; /* internal type value */ int state; + int pending; /* value to be used after next commit */ }; struct cond_node; ==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/security.h#8 (text+ko) ==== @@ -93,5 +93,10 @@ #define security_free_context(ctx) ({ if (ctx) free(ctx, M_SEBSD); }) +int security_get_bool_string(int *len, char *out); +int security_commit_pending_bools(); +int security_set_bool(char *name, int value); +int security_get_bool(char *name, int *value, int *pending); + #endif /* _SELINUX_SECURITY_H_ */ ==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/services.c#9 (text+ko) ==== @@ -1503,6 +1503,39 @@ return rc; } +int security_get_bool_string(int *len, char *out) +{ + int i; + int needed = 1; + int err = 0; + + POLICY_RDLOCK; + for (i = 0; i < policydb.p_bools.nprim; i++) { + needed += 3; + needed += strlen(policydb.p_bool_val_to_name[i]); + } + + if (*len >= needed && out) { + *len = needed; + char *p = out; + + for (i = 0; i < policydb.p_bools.nprim; i++) { + *p++ = '0' + policydb.bool_val_to_struct[i]->state; + *p++ = '0' + policydb.bool_val_to_struct[i]->pending; + strcpy(p, policydb.p_bool_val_to_name[i]); + p += strlen(policydb.p_bool_val_to_name[i]); + *p++ = ';'; + } + *p++ = 0; + } else { + *len = needed; + err = ENOMEM; + } + + POLICY_RDUNLOCK; + return err; +} + int security_get_bools(int *len, char ***names, int **values) { int i, rc = ENOMEM; @@ -1551,6 +1584,72 @@ goto out; } +int security_commit_pending_bools(void) +{ + int i, rc = 0, seqno; + struct cond_node *cur; + + POLICY_WRLOCK; + printk(KERN_INFO "security: committed booleans { "); + for (i = 0; i < policydb.p_bools.nprim; i++) { + policydb.bool_val_to_struct[i]->state = + policydb.bool_val_to_struct[i]->pending; + + if (i != 0) + printk(", "); + printk("%s:%d", policydb.p_bool_val_to_name[i], + policydb.bool_val_to_struct[i]->state); + } + + printk(" }\n"); + + for (cur = policydb.cond_list; cur != NULL; cur = cur->next) { + rc = evaluate_cond_node(&policydb, cur); + if (rc) + goto out; + } + + seqno = ++latest_granting; + +out: + POLICY_WRUNLOCK; + if (!rc) + avc_ss_reset(seqno); + return (rc); +} + +int security_set_bool(char *name, int value) +{ + int i; + POLICY_WRLOCK; + + for (i = 0; i < policydb.p_bools.nprim; i++) + if (!strcmp(name, policydb.p_bool_val_to_name[i])) { + policydb.bool_val_to_struct[i]->pending = value; + POLICY_WRUNLOCK; + return (0); + } + + POLICY_WRUNLOCK; + return (ENOENT); +} + +int security_get_bool(char *name, int *value, int *pending) +{ + int i; + POLICY_RDLOCK; + + for (i = 0; i < policydb.p_bools.nprim; i++) + if (!strcmp(name, policydb.p_bool_val_to_name[i])) { + *pending = policydb.bool_val_to_struct[i]->pending; + *value = policydb.bool_val_to_struct[i]->state; + POLICY_RDUNLOCK; + return (0); + } + + POLICY_RDUNLOCK; + return (ENOENT); +} int security_set_bools(int len, int *values) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200502072010.j17KAxMt035588>