PERFORCE change 114581 for review
Todd Miller
millert at FreeBSD.org
Thu Feb 15 20:26:08 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=114581
Change 114581 by millert at 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, ¬if_lock, "SEBSD Notif Update", MTX_DEF);
#define NOTIF_LOCK mtx_lock(¬if_lock)
#define NOTIF_UNLOCK mtx_unlock(¬if_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 at epoch.ncsc.mil>
*/
+/*
+ * Updated: Hewlett-Packard <paul.moore at 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) <<<
More information about the p4-projects
mailing list