PERFORCE change 70542 for review

Andrew Reisse areisse at FreeBSD.org
Mon Feb 7 12:11:00 PST 2005


http://perforce.freebsd.org/chv.cgi?CH=70542

Change 70542 by areisse at 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)
 {


More information about the p4-projects mailing list