Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 15 Feb 2007 20:26:07 GMT
From:      Todd Miller <millert@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 114581 for review
Message-ID:  <200702152026.l1FKQ7X4073476@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=114581

Change 114581 by millert@millert_p4 on 2007/02/15 20:25:32

	Sync SEBSD module with SELinux kernel tree.

Affected files ...

.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/avc/avc.c#11 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/avc/avc.h#10 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/avc/avc_ss.h#6 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/avtab.c#10 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/avtab.h#8 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/conditional.c#7 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/context.h#6 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/ebitmap.c#6 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/ebitmap.h#6 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/hashtab.c#6 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/hashtab.h#6 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/mls.c#6 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/mls.h#5 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/policydb.c#8 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/policydb.h#9 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/security.h#11 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/services.c#14 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/sidtab.c#11 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/symtab.c#6 edit

Differences ...

==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/avc/avc.c#11 (text+ko) ====

@@ -20,7 +20,6 @@
 
 #include "opt_mac.h"
 
-#include <sys/types.h> 
 #include <sys/param.h>   
 #include <sys/conf.h>
 #include <sys/kernel.h>
@@ -28,6 +27,7 @@
 #include <sys/mount.h>   
 #include <sys/proc.h>
 #include <sys/queue.h>
+#include <sys/socket.h>
 #include <sys/systm.h>
 #include <sys/sysproto.h>
 #include <sys/sysent.h>
@@ -35,6 +35,10 @@
 #include <sys/capability.h>
 #include <machine/atomic.h>
 
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+
 #include <vm/vm.h>
 #include <vm/uma.h>
 
@@ -44,12 +48,7 @@
 #include <security/sebsd/avc/avc.h>
 #include <security/sebsd/avc/avc_ss.h>
 
-static const struct av_perm_to_string
-{
-  u16 tclass;
-  u32 value;
-  const char *name;
-} av_perm_to_string[] = {
+static const struct av_perm_to_string av_perm_to_string[] = {
 #define S_(c, v, s) { c, v, s },
 #include <security/sebsd/avc/av_perm_to_string.h>
 #undef S_
@@ -69,17 +68,21 @@
 #undef TE_
 #undef S_
 
-static const struct av_inherit
-{
-    u16 tclass;
-    const char **common_pts;
-    u32 common_base;
-} av_inherit[] = {
+static const struct av_inherit av_inherit[] = {
 #define S_(c, i, b) { c, common_##i##_perm_to_string, b },
 #include <security/sebsd/avc/av_inherit.h>
 #undef S_
 };
 
+const struct selinux_class_perm selinux_class_perm = {
+	av_perm_to_string,
+	ARRAY_SIZE(av_perm_to_string),
+	class_to_string,
+	ARRAY_SIZE(class_to_string),
+	av_inherit,
+	ARRAY_SIZE(av_inherit)
+};
+
 #define AVC_CACHE_SLOTS			512
 #define AVC_DEF_CACHE_THRESHOLD		512
 #define AVC_CACHE_RECLAIM		16
@@ -92,7 +95,7 @@
 	u32			tsid;
 	u16			tclass;
 	struct av_decision	avd;
-	int			used;	/* used recently */
+	atomic_t		used;	/* used recently */
 };
 
 struct avc_node {
@@ -100,15 +103,10 @@
 	LIST_ENTRY(avc_node)	list;
 };
 
-#define	AVC_LOCK_NAMEFMT	"SEBSD AVC slot %d"
-#define	AVC_LOCK_NAMESIZE	(sizeof(AVC_LOCK_NAMEFMT) + 4)
-
 struct avc_cache {
 	LIST_HEAD(, avc_node)	slots[AVC_CACHE_SLOTS];
-	struct rwlock		slots_lock[AVC_CACHE_SLOTS];
-	char			slots_lockname[AVC_CACHE_SLOTS][AVC_LOCK_NAMESIZE];
 	u32			lru_hint;	/* LRU hint for reclaim scan */
-	u32			active_nodes;
+	atomic_t		active_nodes;
 	u32			latest_notif;	/* latest revocation notification */
 };
 
@@ -125,7 +123,7 @@
 };
 
 /* Exported via selinufs */
-unsigned int avc_cache_threshold = AVC_DEF_CACHE_THRESHOLD;
+int avc_cache_threshold = AVC_DEF_CACHE_THRESHOLD;
 
 #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
 DEFINE_PER_CPU(struct avc_cache_stats, avc_cache_stats) = { 0 };
@@ -134,21 +132,18 @@
 int selinux_auditing = 1;
 int selinux_enforcing = 0;
 
-#define AVC_RDLOCK(n) rw_rlock(&avc_cache.slots_lock[n])
-#define AVC_WRLOCK(n) rw_wlock(&avc_cache.slots_lock[n])
-#define AVC_RDUNLOCK(n) rw_runlock(&avc_cache.slots_lock[n])
-#define AVC_WRUNLOCK(n) rw_wunlock(&avc_cache.slots_lock[n])
+static struct rwlock avc_lock;
+RW_SYSINIT(avc_lock, &avc_lock, "SEBSD avc lock");
+#define AVC_RDLOCK rw_rlock(&avc_lock)
+#define AVC_WRLOCK rw_wlock(&avc_lock)
+#define AVC_RDUNLOCK rw_runlock(&avc_lock)
+#define AVC_WRUNLOCK rw_wunlock(&avc_lock)
 
 static struct mtx notif_lock;
 MTX_SYSINIT(notif_lock, &notif_lock, "SEBSD Notif Update", MTX_DEF);
 #define NOTIF_LOCK mtx_lock(&notif_lock)
 #define NOTIF_UNLOCK mtx_unlock(&notif_lock)
 
-static struct mtx ratelimit_lock;
-MTX_SYSINIT(ratelimit_lock, &ratelimit_lock, "SEBSD Ratelimit", MTX_DEF);
-#define RATELIM_LOCK mtx_lock(&ratelimit_lock)
-#define RATELIM_UNLOCK mtx_unlock(&ratelimit_lock) 
-
 static struct avc_cache avc_cache;
 static struct avc_callback_node *avc_callbacks;
 static uma_zone_t avc_node_cachep;
@@ -256,11 +251,10 @@
 {
 	int i;
 
+	avc_audit_init();
+
 	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
 		LIST_INIT(&avc_cache.slots[i]);
-		snprintf(avc_cache.slots_lockname[i],
-		    sizeof(avc_cache.slots_lockname[i]), AVC_LOCK_NAMEFMT, i);
-		rw_init(&avc_cache.slots_lock[i], avc_cache.slots_lockname[i]);
 	}
 	avc_cache.active_nodes = 0;
 	avc_cache.lru_hint = 0;
@@ -268,10 +262,10 @@
 	avc_node_cachep = uma_zcreate("avc_node", sizeof(struct avc_node),
 				      NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
 
-	audit_log("AVC INITIALIZED");
-
 	/* The fetch may or may not occur; if not, it doesn't change int *. */
 	TUNABLE_INT_FETCH("security.mac.sebsd.enforcing", &selinux_enforcing);
+
+	printf("AVC INITIALIZED\n");	/* XXX */
 }
 
 #if 0
@@ -280,10 +274,11 @@
 	int i, chain_len, max_chain_len, slots_used;
 	struct avc_node *node;
 
+	AVC_RDLOCK;
+
 	slots_used = 0;
 	max_chain_len = 0;
 	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
-		AVC_RDLOCK(i);
 		if (!LIST_EMPTY(&avc_cache.slots[i])) {
 			slots_used++;
 			chain_len = 0;
@@ -292,9 +287,10 @@
 			if (chain_len > max_chain_len)
 				max_chain_len = chain_len;
 		}
-		AVC_RDUNLOCK(i);
 	}
 
+	AVC_RDUNLOCK;
+
 	return scnprintf(page, PAGE_SIZE, "entries: %d\nbuckets used: %d/%d\n"
 			 "longest chain: %d\n",
 			 atomic_read(&avc_cache.active_nodes),
@@ -339,10 +335,12 @@
 	struct avc_node *node, *next;
 	int hvalue, try, ecx;
 
+	AVC_WRLOCK;
+
+	hvalue = avc_cache.lru_hint;
 	for (try = 0, ecx = 0; try < AVC_CACHE_SLOTS; try++ ) {
-		hvalue = atomic_inc_return(&avc_cache.lru_hint) & (AVC_CACHE_SLOTS - 1);
+		hvalue = (hvalue + 1) & (AVC_CACHE_SLOTS - 1);
 
-		AVC_WRLOCK(hvalue);
 		for (node = LIST_FIRST(&avc_cache.slots[hvalue]);
 		    node != NULL; node = next) {
 			next = LIST_NEXT(node, list);
@@ -351,15 +349,14 @@
 				avc_node_delete(node);
 				avc_cache_stats_incr(reclaims);
 				ecx++;
-				if (ecx >= AVC_CACHE_RECLAIM) {
-					AVC_WRUNLOCK(hvalue);
+				if (ecx >= AVC_CACHE_RECLAIM)
 					goto out;
-				}
 			}
 		}
-		AVC_WRUNLOCK(hvalue);
 	}
 out:
+	avc_cache.lru_hint = hvalue;
+	AVC_WRUNLOCK;
 	return ecx;
 }
 
@@ -389,17 +386,13 @@
 	memcpy(&node->ae.avd, &ae->avd, sizeof(node->ae.avd));
 }
 
-/*
- * Note: returns with read lock held for hvalue.
- */
-static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid, u16 tclass,
-    int *hvaluep)
+static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid, u16 tclass)
 {
 	struct avc_node *node, *ret = NULL;
+	int hvalue;
 
-	*hvaluep = avc_hash(ssid, tsid, tclass);
-	AVC_RDLOCK(*hvaluep);
-	LIST_FOREACH(node, &avc_cache.slots[*hvaluep], list) {
+	hvalue = avc_hash(ssid, tsid, tclass);
+	LIST_FOREACH(node, &avc_cache.slots[hvalue], list) {
 		if (ssid == node->ae.ssid &&
 		    tclass == node->ae.tclass &&
 		    tsid == node->ae.tsid) {
@@ -426,35 +419,33 @@
  * @tsid: target security identifier
  * @tclass: target security class
  * @requested: requested permissions, interpreted based on @tclass
- * @hvaluep: cache slot of the node on success
  *
  * Look up an AVC entry that is valid for the
  * @requested permissions between the SID pair
  * (@ssid, @tsid), interpreting the permissions
  * based on @tclass.  If a valid AVC entry exists,
- * then this function return the avc_node and read locks its slot.
+ * then this function return the avc_node.
  * Otherwise, this function returns NULL.
  */
-static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass, u32 requested, int *hvaluep)
+static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass, u32 requested)
 {
 	struct avc_node *node;
 
 	avc_cache_stats_incr(lookups);
-	node = avc_search_node(ssid, tsid, tclass, hvaluep);
+	node = avc_search_node(ssid, tsid, tclass);
 
 	if (node && ((node->ae.avd.decided & requested) == requested)) {
 		avc_cache_stats_incr(hits);
 		goto out;
 	}
 
-	AVC_RDUNLOCK(*hvaluep);
 	node = NULL;
 	avc_cache_stats_incr(misses);
 out:
 	return node;
 }
 
-static int avc_latest_notif_update(int seqno, int is_insert)
+static int avc_latest_notif_update(u32 seqno, int is_insert)
 {
 	int ret = 0;
 
@@ -480,7 +471,6 @@
  * @tsid: target security identifier
  * @tclass: target security class
  * @ae: AVC entry
- * @hvaluep: cache slot of the node on success
  *
  * Insert an AVC entry for the SID pair
  * (@ssid, @tsid) and class @tclass.
@@ -489,112 +479,61 @@
  * response to a security_compute_av() call.  If the
  * sequence number @ae->avd.seqno is not less than the latest
  * revocation notification, then the function copies
- * the access vectors into a cache entry, returns (WRITE-locked)
+ * the access vectors into a cache entry, returns
  * avc_node inserted. Otherwise, this function returns NULL.
  */
-static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, struct avc_entry *ae, int *hvaluep)
+static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, struct avc_entry *ae)
 {
 	struct avc_node *pos, *node;
+	int hvalue;
 
 	if (avc_latest_notif_update(ae->avd.seqno, 1))
 		return NULL;
 
 	node = avc_alloc_node();
 	if (node) {
-		*hvaluep = avc_hash(ssid, tsid, tclass);
+		hvalue = avc_hash(ssid, tsid, tclass);
 		avc_node_populate(node, ssid, tsid, tclass, ae);
 
-		AVC_WRLOCK(*hvaluep);
+		AVC_WRLOCK;
 
-		LIST_FOREACH(pos, &avc_cache.slots[*hvaluep], list) {
+		LIST_FOREACH(pos, &avc_cache.slots[hvalue], list) {
 			if (pos->ae.ssid == ssid &&
 			    pos->ae.tsid == tsid &&
 			    pos->ae.tclass == tclass) {
 			    	avc_node_replace(node, pos);
+				AVC_WRUNLOCK;
 				goto found;
 			}
 		}
-		LIST_INSERT_HEAD(&avc_cache.slots[*hvaluep], node, list);
+		LIST_INSERT_HEAD(&avc_cache.slots[hvalue], node, list);
+		AVC_WRUNLOCK;
 	}
 found:
 	return node;
 }
 
-#ifdef __linux__
 static inline void avc_print_ipv6_addr(struct audit_buffer *ab,
 				       struct in6_addr *addr, __be16 port,
-				       char *name1, char *name2)
+				       const char *name1, const char *name2)
 {
-	if (!ipv6_addr_any(addr))
-		audit_log_format(ab, " %s=" NIP6_FMT, name1, NIP6(*addr));
+	if (!IN6_IS_ADDR_UNSPECIFIED(addr))
+		audit_log_format(ab, " %s=%s", name1, ip6_sprintf(addr));
 	if (port)
 		audit_log_format(ab, " %s=%d", name2, ntohs(port));
 }
 
-static inline void avc_print_ipv4_addr(struct audit_buffer *ab, u32 addr,
-				       __be16 port, char *name1, char *name2)
+static inline void avc_print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
+				       __be16 port, const char *name1,
+				       const char *name2)
 {
-	if (addr)
-		audit_log_format(ab, " %s=" NIPQUAD_FMT, name1, NIPQUAD(addr));
+	if (addr != INADDR_ANY)
+		audit_log_format(ab, " %s=%ld.%ld.%ld.%ld", name1,
+		    (ntohl(addr)>>24)&0xFF, (ntohl(addr)>>16)&0xFF,
+		    (ntohl(addr)>>8)&0xFF, (ntohl(addr))&0xFF);
 	if (port)
 		audit_log_format(ab, " %s=%d", name2, ntohs(port));
 }
-#endif /* __linux__ */
-
-
-#define AVC_MSG_COST	5
-#define AVC_MSG_BURST	10*5
-
-/*
- * This enforces a rate limit: not more than one kernel message
- * every 5secs to make a denial-of-service attack impossible.
- */
-static int avc_ratelimit(void)
-{
-	static int toks;
-	static int last_msg;
-	static int missed, rc;
-	int now = ticks;
-
-	RATELIM_LOCK;
-	toks += now - last_msg;
-	last_msg = now;
-	if (toks > AVC_MSG_BURST)
-		toks = AVC_MSG_BURST;
-	if (toks >= AVC_MSG_COST) {
-		int lost = missed;
-		missed = 0;
-		toks -= AVC_MSG_COST;
-		RATELIM_UNLOCK;
-		if (lost)
-			printk(KERN_WARNING "AVC: %d messages suppressed.\n",
-			       lost);
-		rc = 1;
-		goto out;
-	}
-	missed++;
-	RATELIM_UNLOCK;
-out:
-	return rc;
-}
-
-static inline int check_avc_ratelimit(void)
-{
-
-	/*
-	 * If auditing is not enabled, suppress all messages.
-	 */
-	if (!selinux_auditing)
-		return 0;
-
-	/*
-	 * If in permissive mode, display all messages.
-	 */
-	if (!selinux_enforcing)
-		return 1;
-
-	return avc_ratelimit();
-}
 
 /**
  * avc_audit - Audit the granting or denial of permissions.
@@ -619,7 +558,7 @@
                u16 tclass, u32 requested,
                struct av_decision *avd, int result, struct avc_audit_data *a)
 {
-	struct proc *tsk = curproc;
+	struct proc *tsk;
 	u32 denied, audited;
 	struct audit_buffer *ab;
 
@@ -636,19 +575,16 @@
 			return;
 	}
 
-	if (!check_avc_ratelimit())
-		return;
-
-	ab = audit_log_start();
+	ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_AVC);
 	if (!ab)
 		return;		/* audit_panic has been called */
 	audit_log_format(ab, "avc:  %s ", denied ? "denied" : "granted");
 	avc_dump_av(ab, tclass,audited);
-	audit_log_format(ab, " for ");
-#ifdef __linux__
+	audit_log_format(ab, " for");
 	if (a && a->tsk)
 		tsk = a->tsk;
-#endif
+	else
+		tsk = curproc;	/* XXX, should be set by caller */
 	if (tsk && tsk->p_pid) {
 		audit_log_format(ab, " pid=%d comm=", tsk->p_pid);
 		audit_log_untrustedstring(ab, tsk->p_comm);
@@ -676,7 +612,7 @@
 						 curthread)) {
 					audit_log_format(ab,
 					    " inode=%ld, mountpoint=%s, ",
-					    va.va_fileid, 
+					    va.va_fileid,
 					    vp->v_mount->mnt_stat.f_mntonname);
 				} else {
 					audit_log_format(ab,
@@ -736,6 +672,7 @@
 					break;
 				}
 			}
+#endif /* __linux__ */
 			
 			switch (a->u.net.family) {
 			case AF_INET:
@@ -756,9 +693,8 @@
 				break;
 			}
 			if (a->u.net.netif)
-				audit_log_format(ab, " netif=%s",
-					a->u.net.netif);
-#endif /* __linux__ */
+				audit_log_format(ab, " netif=%s%d",
+					a->u.net.netif, a->u.net.netif_unit);
 			break;
 		}
 	}
@@ -767,6 +703,7 @@
 	audit_log_end(ab);
 }
 
+#ifdef __linux__
 /**
  * avc_add_callback - Register a callback for security events.
  * @callback: callback function
@@ -807,6 +744,7 @@
 out:
 	return rc;
 }
+#endif
 
 static inline int avc_sidcmp(u32 x, u32 y)
 {
@@ -835,9 +773,9 @@
 		goto out;
 	}
 
-	/* Lock the target slot */
 	hvalue = avc_hash(ssid, tsid, tclass);
-	AVC_WRLOCK(hvalue);
+
+	AVC_WRLOCK;
 
 	LIST_FOREACH(pos, &avc_cache.slots[hvalue], list){
 		if ( ssid==pos->ae.ssid &&
@@ -883,7 +821,7 @@
 	}
 	avc_node_replace(node, orig);
 out_unlock:
-	AVC_WRUNLOCK(hvalue);
+	AVC_WRUNLOCK;
 out:
 	return rc;
 }
@@ -895,28 +833,30 @@
 int avc_ss_reset(u32 seqno)
 {
 	struct avc_callback_node *c;
-	int i, rc = 0;
+	int i, rc = 0, tmprc;
 	struct avc_node *node;
 
+	AVC_WRLOCK;
 
 	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
-		AVC_WRLOCK(i);
 		while ((node = LIST_FIRST(&avc_cache.slots[i])) != NULL)
 			avc_node_delete(node);
-		AVC_WRUNLOCK(i);
 	}
 
+	AVC_WRUNLOCK;
+
 	for (c = avc_callbacks; c; c = c->next) {
 		if (c->events & AVC_CALLBACK_RESET) {
-			rc = c->callback(AVC_CALLBACK_RESET,
-					 0, 0, 0, 0, NULL);
-			if (rc)
-				goto out;
+			tmprc = c->callback(AVC_CALLBACK_RESET,
+			                    0, 0, 0, 0, NULL);
+			/* save the first error encountered for the return
+			   value and continue processing the callbacks */
+			if (!rc)
+				rc = tmprc;
 		}
 	}
 
 	avc_latest_notif_update(seqno, 0);
-out:
 	return rc;
 }
 
@@ -945,29 +885,28 @@
 {
 	struct avc_node *node;
 	struct avc_entry entry, *p_ae;
-	int hvalue, found, rc = 0;
+	int rc = 0;
 	u32 denied;
 
-	node = avc_lookup(ssid, tsid, tclass, requested, &hvalue);
-	found = node != NULL;
+	AVC_RDLOCK;
+	node = avc_lookup(ssid, tsid, tclass, requested);
+	AVC_RDUNLOCK;
 
-	if (!found) {
+	if (!node) {
 		rc = security_compute_av(ssid,tsid,tclass,requested,&entry.avd);
 		if (rc)
 			goto out;
-		node = avc_insert(ssid,tsid,tclass,&entry,&hvalue);
+		node = avc_insert(ssid,tsid,tclass,&entry);
 	}
 
+	AVC_RDLOCK;
 	p_ae = node ? &node->ae : &entry;
 
 	if (avd)
 		memcpy(avd, &p_ae->avd, sizeof(*avd));
 
 	denied = requested & ~(p_ae->avd.allowed);
-	if (found)
-		AVC_RDUNLOCK(hvalue);		/* locked by avc_lookup() */
-	else if (node)
-		AVC_WRUNLOCK(hvalue);		/* locked by avc_insert() */
+	AVC_RDUNLOCK;
 
 	if (!requested || denied) {
 		if (selinux_enforcing)

==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/avc/avc.h#10 (text+ko) ====

@@ -34,12 +34,8 @@
  */
 struct avc_entry;
 
-struct task_struct;
-struct vfsmount;
-struct dentry;
-struct inode;
-struct sock;
-struct sk_buff;
+struct proc;
+struct socket;
 
 /* Auxiliary data to use in generating the audit record. */
 struct avc_audit_data {
@@ -48,23 +44,25 @@
 #define AVC_AUDIT_DATA_NET  2
 #define AVC_AUDIT_DATA_CAP  3
 #define AVC_AUDIT_DATA_IPC  4
-#ifdef __linux__
-	struct task_struct *tsk;
-#endif
+#define AVC_AUDIT_DATA_MIG  5
+	struct proc *tsk;
 	union 	{
 		struct {
 			struct vnode *vp;
+			char *path;
+			int pathlen;
 		} fs;
 		struct {
-			char *netif;
-			struct sock *sk;
+			const char *netif;
+			u32 netif_unit;
+			struct socket *so;
 			u16 family;
-			u16 dport;
-			u16 sport;
+			__be16 dport;
+			__be16 sport;
 			union {
 				struct {
-					u32 daddr;
-					u32 saddr;
+					__be32 daddr;
+					__be32 saddr;
 				} v4;
 				struct {
 					struct in6_addr daddr;
@@ -89,12 +87,12 @@
  */
 struct avc_cache_stats
 {
-	unsigned int lookups;
-	unsigned int hits;
-	unsigned int misses;
-	unsigned int allocations;
-	unsigned int reclaims;
-	unsigned int frees;
+	atomic_t lookups;
+	atomic_t hits;
+	atomic_t misses;
+	atomic_t allocations;
+	atomic_t reclaims;
+	atomic_t frees;
 };
 
 /*
@@ -132,11 +130,13 @@
 
 /* Exported to selinuxfs */
 int avc_get_hash_stats(char *page);
-extern unsigned int avc_cache_threshold;
+extern int avc_cache_threshold;
 
 #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
 DECLARE_PER_CPU(struct avc_cache_stats, avc_cache_stats);
 #endif
 
+void avc_audit_init(void);
+
 #endif /* _SELINUX_AVC_H_ */
 

==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/avc/avc_ss.h#6 (text+ko) ====

@@ -11,5 +11,29 @@
 
 int avc_ss_reset(u32 seqno);
 
+struct av_perm_to_string
+{
+	u16 tclass;
+	u32 value;
+	const char *name;
+};
+
+struct av_inherit
+{
+	u16 tclass;
+	const char **common_pts;
+	u32 common_base;
+};
+
+struct selinux_class_perm
+{
+	const struct av_perm_to_string *av_perm_to_string;
+	u32 av_pts_len;
+	const char **class_to_string;
+	u32 cts_len;
+	const struct av_inherit *av_inherit;
+	u32 av_inherit_len;
+};
+
 #endif /* _SELINUX_AVC_SS_H_ */
 

==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/avtab.c#10 (text+ko) ====

@@ -305,7 +305,8 @@
 	u32 items, items2, val;
 	struct avtab_key key;
 	struct avtab_datum datum;
-	int i, rc;
+	size_t i;
+	int rc;
 
 	memset(&key, 0, sizeof(struct avtab_key));
 	memset(&datum, 0, sizeof(struct avtab_datum));

==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/avtab.h#8 (text+ko) ====

@@ -57,7 +57,7 @@
 void avtab_destroy(struct avtab *h);
 void avtab_hash_eval(struct avtab *h, char *tag);
 
-int avtab_read_item(void *fp, uint32_t vers, struct avtab *a,
+int avtab_read_item(void *fp, u32 vers, struct avtab *a,
 		    int (*insert)(struct avtab *a, struct avtab_key *k,
 				  struct avtab_datum *d, void *p),
 		    void *p);

==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/conditional.c#7 (text+ko) ====

@@ -342,9 +342,10 @@
 
 static int cond_read_av_list(struct policydb *p, void *fp, struct cond_av_list **ret_list, struct cond_av_list *other)
 {
-	int i, rc;
+	int rc;
 	__le32 buf[1];
 	u32 len;
+	size_t i;
 	struct cond_insertf_data data;
 
 	*ret_list = NULL;

==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/context.h#6 (text+ko) ====

@@ -55,6 +55,29 @@
 	return rc;
 }
 
+/*
+ * Sets both levels in the MLS range of 'dst' to the low level of 'src'.
+ */
+static inline int mls_context_cpy_low(struct context *dst, struct context *src)
+{
+	int rc;
+
+	if (!selinux_mls_enabled)
+		return 0;
+
+	dst->range.level[0].sens = src->range.level[0].sens;
+	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
+	if (rc)
+		goto out;
+
+	dst->range.level[1].sens = src->range.level[0].sens;
+	rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[0].cat);
+	if (rc)
+		ebitmap_destroy(&dst->range.level[0].cat);
+out:
+	return rc;
+}
+
 static inline int mls_context_cmp(struct context *c1, struct context *c2)
 {
 	if (!selinux_mls_enabled)
@@ -104,3 +127,4 @@
 }
 
 #endif	/* _SS_CONTEXT_H_ */
+

==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/ebitmap.c#6 (text+ko) ====

@@ -3,6 +3,13 @@
  *
  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
  */
+/*
+ * Updated: Hewlett-Packard <paul.moore@hp.com>
+ *
+ *	Added support to import/export the NetLabel category bitmap
+ *
+ * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
+ */
 
 #include <security/sebsd/ss/ebitmap.h>
 #include <security/sebsd/ss/policydb.h>
@@ -57,6 +64,121 @@
 	return 0;
 }
 
+#ifdef CONFIG_NETLABEL
+/**
+ * ebitmap_netlbl_export - Export an ebitmap into a NetLabel category bitmap
+ * @ebmap: the ebitmap to export
+ * @catmap: the NetLabel category bitmap
+ *
+ * Description:
+ * Export a SELinux extensibile bitmap into a NetLabel category bitmap.
+ * Returns zero on success, negative values on error.
+ *
+ */
+int ebitmap_netlbl_export(struct ebitmap *ebmap,
+			  struct netlbl_lsm_secattr_catmap **catmap)
+{
+	struct ebitmap_node *e_iter = ebmap->node;
+	struct netlbl_lsm_secattr_catmap *c_iter;
+	u32 cmap_idx;
+
+	/* This function is a much simpler because SELinux's MAPTYPE happens
+	 * to be the same as NetLabel's NETLBL_CATMAP_MAPTYPE, if MAPTYPE is
+	 * changed from a u64 this function will most likely need to be changed
+	 * as well.  It's not ideal but I think the tradeoff in terms of
+	 * neatness and speed is worth it. */
+
+	if (e_iter == NULL) {
+		*catmap = NULL;
+		return 0;
+	}
+
+	c_iter = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
+	if (c_iter == NULL)
+		return ENOMEM;
+	*catmap = c_iter;
+	c_iter->startbit = e_iter->startbit & ~(NETLBL_CATMAP_SIZE - 1);
+
+	while (e_iter != NULL) {
+		if (e_iter->startbit >=
+		    (c_iter->startbit + NETLBL_CATMAP_SIZE)) {
+			c_iter->next = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
+			if (c_iter->next == NULL)
+				goto netlbl_export_failure;
+			c_iter = c_iter->next;
+			c_iter->startbit = e_iter->startbit &
+				           ~(NETLBL_CATMAP_SIZE - 1);
+		}
+		cmap_idx = (e_iter->startbit - c_iter->startbit) /
+			   NETLBL_CATMAP_MAPSIZE;
+		c_iter->bitmap[cmap_idx] = e_iter->map;
+		e_iter = e_iter->next;
+	}
+
+	return 0;
+
+netlbl_export_failure:
+	netlbl_secattr_catmap_free(*catmap);
+	return ENOMEM;
+}
+
+/**
+ * ebitmap_netlbl_import - Import a NetLabel category bitmap into an ebitmap
+ * @ebmap: the ebitmap to export
+ * @catmap: the NetLabel category bitmap
+ *
+ * Description:
+ * Import a NetLabel category bitmap into a SELinux extensibile bitmap.
+ * Returns zero on success, negative values on error.
+ *
+ */
+int ebitmap_netlbl_import(struct ebitmap *ebmap,
+			  struct netlbl_lsm_secattr_catmap *catmap)
+{
+	struct ebitmap_node *e_iter = NULL;
+	struct ebitmap_node *emap_prev = NULL;
+	struct netlbl_lsm_secattr_catmap *c_iter = catmap;
+	u32 c_idx;
+
+	/* This function is a much simpler because SELinux's MAPTYPE happens
+	 * to be the same as NetLabel's NETLBL_CATMAP_MAPTYPE, if MAPTYPE is
+	 * changed from a u64 this function will most likely need to be changed
+	 * as well.  It's not ideal but I think the tradeoff in terms of
+	 * neatness and speed is worth it. */
+
+	do {
+		for (c_idx = 0; c_idx < NETLBL_CATMAP_MAPCNT; c_idx++) {
+			if (c_iter->bitmap[c_idx] == 0)
+				continue;
+
+			e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC);
+			if (e_iter == NULL)
+				goto netlbl_import_failure;
+			if (emap_prev == NULL)
+				ebmap->node = e_iter;
+			else
+				emap_prev->next = e_iter;
+			emap_prev = e_iter;
+
+			e_iter->startbit = c_iter->startbit +
+				           NETLBL_CATMAP_MAPSIZE * c_idx;
+			e_iter->map = c_iter->bitmap[c_idx];
+		}
+		c_iter = c_iter->next;
+	} while (c_iter != NULL);
+	if (e_iter != NULL)
+		ebmap->highbit = e_iter->startbit + MAPSIZE;
+	else
+		ebitmap_destroy(ebmap);
+
+	return 0;
+
+netlbl_import_failure:
+	ebitmap_destroy(ebmap);
+	return ENOMEM;
+}
+#endif /* CONFIG_NETLABEL */
+
 int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2)
 {
 	struct ebitmap_node *n1, *n2;

==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/ebitmap.h#6 (text+ko) ====

@@ -79,4 +79,24 @@
 void ebitmap_destroy(struct ebitmap *e);
 int ebitmap_read(struct ebitmap *e, void *fp);
 
+#ifdef __linux__
+#ifdef CONFIG_NETLABEL
+int ebitmap_netlbl_export(struct ebitmap *ebmap,
+			  struct netlbl_lsm_secattr_catmap **catmap);
+int ebitmap_netlbl_import(struct ebitmap *ebmap,
+			  struct netlbl_lsm_secattr_catmap *catmap);
+#else
+static inline int ebitmap_netlbl_export(struct ebitmap *ebmap,
+				struct netlbl_lsm_secattr_catmap **catmap)
+{
+	return ENOMEM;
+}
+static inline int ebitmap_netlbl_import(struct ebitmap *ebmap,
+				struct netlbl_lsm_secattr_catmap *catmap)
+{
+	return ENOMEM;
+}
+#endif
+#endif
+
 #endif	/* _SS_EBITMAP_H_ */

==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/ss/hashtab.c#6 (text+ko) ====

@@ -10,8 +10,8 @@
 #include <sys/errno.h>
 #include <sys/libkern.h>
 
-struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, void *key),
-                               int (*keycmp)(struct hashtab *h, void *key1, void *key2),

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200702152026.l1FKQ7X4073476>