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, ¬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@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>