Commit aa8e712c authored by Stephen Smalley's avatar Stephen Smalley Committed by Paul Moore

selinux: wrap global selinux state

Define a selinux state structure (struct selinux_state) for
global SELinux state and pass it explicitly to all security server
functions.  The public portion of the structure contains state
that is used throughout the SELinux code, such as the enforcing mode.
The structure also contains a pointer to a selinux_ss structure whose
definition is private to the security server and contains security
server specific state such as the policy database and SID table.

This change should have no effect on SELinux behavior or APIs
(userspace or LSM).  It merely wraps SELinux state and passes it
explicitly as needed.
Signed-off-by: default avatarStephen Smalley <sds@tycho.nsa.gov>
[PM: minor fixups needed due to collisions with the SCTP patches]
Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
parent 2572f5b4
...@@ -149,7 +149,8 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla ...@@ -149,7 +149,8 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla
char *scontext; char *scontext;
u32 scontext_len; u32 scontext_len;
rc = security_sid_to_context(ssid, &scontext, &scontext_len); rc = security_sid_to_context(&selinux_state, ssid,
&scontext, &scontext_len);
if (rc) if (rc)
audit_log_format(ab, "ssid=%d", ssid); audit_log_format(ab, "ssid=%d", ssid);
else { else {
...@@ -157,7 +158,8 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla ...@@ -157,7 +158,8 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla
kfree(scontext); kfree(scontext);
} }
rc = security_sid_to_context(tsid, &scontext, &scontext_len); rc = security_sid_to_context(&selinux_state, tsid,
&scontext, &scontext_len);
if (rc) if (rc)
audit_log_format(ab, " tsid=%d", tsid); audit_log_format(ab, " tsid=%d", tsid);
else { else {
...@@ -969,7 +971,8 @@ static noinline struct avc_node *avc_compute_av(u32 ssid, u32 tsid, ...@@ -969,7 +971,8 @@ static noinline struct avc_node *avc_compute_av(u32 ssid, u32 tsid,
{ {
rcu_read_unlock(); rcu_read_unlock();
INIT_LIST_HEAD(&xp_node->xpd_head); INIT_LIST_HEAD(&xp_node->xpd_head);
security_compute_av(ssid, tsid, tclass, avd, &xp_node->xp); security_compute_av(&selinux_state, ssid, tsid, tclass,
avd, &xp_node->xp);
rcu_read_lock(); rcu_read_lock();
return avc_insert(ssid, tsid, tclass, avd, xp_node); return avc_insert(ssid, tsid, tclass, avd, xp_node);
} }
...@@ -982,7 +985,8 @@ static noinline int avc_denied(u32 ssid, u32 tsid, ...@@ -982,7 +985,8 @@ static noinline int avc_denied(u32 ssid, u32 tsid,
if (flags & AVC_STRICT) if (flags & AVC_STRICT)
return -EACCES; return -EACCES;
if (selinux_enforcing && !(avd->flags & AVD_FLAGS_PERMISSIVE)) if (is_enforcing(&selinux_state) &&
!(avd->flags & AVD_FLAGS_PERMISSIVE))
return -EACCES; return -EACCES;
avc_update_node(AVC_CALLBACK_GRANT, requested, driver, xperm, ssid, avc_update_node(AVC_CALLBACK_GRANT, requested, driver, xperm, ssid,
...@@ -1043,8 +1047,8 @@ int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested, ...@@ -1043,8 +1047,8 @@ int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested,
goto decision; goto decision;
} }
rcu_read_unlock(); rcu_read_unlock();
security_compute_xperms_decision(ssid, tsid, tclass, driver, security_compute_xperms_decision(&selinux_state, ssid, tsid,
&local_xpd); tclass, driver, &local_xpd);
rcu_read_lock(); rcu_read_lock();
avc_update_node(AVC_CALLBACK_ADD_XPERMS, requested, driver, xperm, avc_update_node(AVC_CALLBACK_ADD_XPERMS, requested, driver, xperm,
ssid, tsid, tclass, avd.seqno, &local_xpd, 0); ssid, tsid, tclass, avd.seqno, &local_xpd, 0);
......
This diff is collapsed.
...@@ -152,7 +152,8 @@ static int sel_ib_pkey_sid_slow(u64 subnet_prefix, u16 pkey_num, u32 *sid) ...@@ -152,7 +152,8 @@ static int sel_ib_pkey_sid_slow(u64 subnet_prefix, u16 pkey_num, u32 *sid)
return 0; return 0;
} }
ret = security_ib_pkey_sid(subnet_prefix, pkey_num, sid); ret = security_ib_pkey_sid(&selinux_state, subnet_prefix, pkey_num,
sid);
if (ret) if (ret)
goto out; goto out;
......
...@@ -20,12 +20,6 @@ ...@@ -20,12 +20,6 @@
#include "av_permissions.h" #include "av_permissions.h"
#include "security.h" #include "security.h"
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
extern int selinux_enforcing;
#else
#define selinux_enforcing 1
#endif
/* /*
* An entry in the AVC. * An entry in the AVC.
*/ */
......
...@@ -19,11 +19,5 @@ struct security_class_mapping { ...@@ -19,11 +19,5 @@ struct security_class_mapping {
extern struct security_class_mapping secclass_map[]; extern struct security_class_mapping secclass_map[];
/*
* The security server must be initialized before
* any labeling or access decisions can be provided.
*/
extern int ss_initialized;
#endif /* _SELINUX_AVC_SS_H_ */ #endif /* _SELINUX_AVC_SS_H_ */
...@@ -13,10 +13,15 @@ ...@@ -13,10 +13,15 @@
#ifndef _SELINUX_CONDITIONAL_H_ #ifndef _SELINUX_CONDITIONAL_H_
#define _SELINUX_CONDITIONAL_H_ #define _SELINUX_CONDITIONAL_H_
int security_get_bools(int *len, char ***names, int **values); #include "security.h"
int security_set_bools(int len, int *values); int security_get_bools(struct selinux_state *state,
int *len, char ***names, int **values);
int security_get_bool_value(int index); int security_set_bools(struct selinux_state *state,
int len, int *values);
int security_get_bool_value(struct selinux_state *state,
int index);
#endif #endif
...@@ -158,6 +158,4 @@ struct bpf_security_struct { ...@@ -158,6 +158,4 @@ struct bpf_security_struct {
u32 sid; /*SID of bpf obj creater*/ u32 sid; /*SID of bpf obj creater*/
}; };
extern unsigned int selinux_checkreqprot;
#endif /* _SELINUX_OBJSEC_H_ */ #endif /* _SELINUX_OBJSEC_H_ */
This diff is collapsed.
...@@ -163,7 +163,7 @@ static int sel_netif_sid_slow(struct net *ns, int ifindex, u32 *sid) ...@@ -163,7 +163,7 @@ static int sel_netif_sid_slow(struct net *ns, int ifindex, u32 *sid)
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
ret = security_netif_sid(dev->name, &new->nsec.sid); ret = security_netif_sid(&selinux_state, dev->name, &new->nsec.sid);
if (ret != 0) if (ret != 0)
goto out; goto out;
new->nsec.ns = ns; new->nsec.ns = ns;
......
...@@ -59,7 +59,7 @@ static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb, ...@@ -59,7 +59,7 @@ static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,
{ {
int rc; int rc;
rc = security_netlbl_secattr_to_sid(secattr, sid); rc = security_netlbl_secattr_to_sid(&selinux_state, secattr, sid);
if (rc == 0 && if (rc == 0 &&
(secattr->flags & NETLBL_SECATTR_CACHEABLE) && (secattr->flags & NETLBL_SECATTR_CACHEABLE) &&
(secattr->flags & NETLBL_SECATTR_CACHE)) (secattr->flags & NETLBL_SECATTR_CACHE))
...@@ -90,7 +90,8 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk) ...@@ -90,7 +90,8 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk)
secattr = netlbl_secattr_alloc(GFP_ATOMIC); secattr = netlbl_secattr_alloc(GFP_ATOMIC);
if (secattr == NULL) if (secattr == NULL)
return NULL; return NULL;
rc = security_netlbl_sid_to_secattr(sksec->sid, secattr); rc = security_netlbl_sid_to_secattr(&selinux_state, sksec->sid,
secattr);
if (rc != 0) { if (rc != 0) {
netlbl_secattr_free(secattr); netlbl_secattr_free(secattr);
return NULL; return NULL;
...@@ -257,7 +258,8 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, ...@@ -257,7 +258,8 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
if (secattr == NULL) { if (secattr == NULL) {
secattr = &secattr_storage; secattr = &secattr_storage;
netlbl_secattr_init(secattr); netlbl_secattr_init(secattr);
rc = security_netlbl_sid_to_secattr(sid, secattr); rc = security_netlbl_sid_to_secattr(&selinux_state, sid,
secattr);
if (rc != 0) if (rc != 0)
goto skbuff_setsid_return; goto skbuff_setsid_return;
} }
...@@ -297,7 +299,8 @@ int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep, ...@@ -297,7 +299,8 @@ int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep,
return 0; return 0;
netlbl_secattr_init(&secattr); netlbl_secattr_init(&secattr);
rc = security_netlbl_sid_to_secattr(ep->secid, &secattr); rc = security_netlbl_sid_to_secattr(&selinux_state,
ep->secid, &secattr);
if (rc != 0) if (rc != 0)
goto assoc_request_return; goto assoc_request_return;
...@@ -345,7 +348,8 @@ int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family) ...@@ -345,7 +348,8 @@ int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family)
return 0; return 0;
netlbl_secattr_init(&secattr); netlbl_secattr_init(&secattr);
rc = security_netlbl_sid_to_secattr(req->secid, &secattr); rc = security_netlbl_sid_to_secattr(&selinux_state, req->secid,
&secattr);
if (rc != 0) if (rc != 0)
goto inet_conn_request_return; goto inet_conn_request_return;
rc = netlbl_req_setattr(req, &secattr); rc = netlbl_req_setattr(req, &secattr);
......
...@@ -215,12 +215,12 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid) ...@@ -215,12 +215,12 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
goto out; goto out;
switch (family) { switch (family) {
case PF_INET: case PF_INET:
ret = security_node_sid(PF_INET, ret = security_node_sid(&selinux_state, PF_INET,
addr, sizeof(struct in_addr), sid); addr, sizeof(struct in_addr), sid);
new->nsec.addr.ipv4 = *(__be32 *)addr; new->nsec.addr.ipv4 = *(__be32 *)addr;
break; break;
case PF_INET6: case PF_INET6:
ret = security_node_sid(PF_INET6, ret = security_node_sid(&selinux_state, PF_INET6,
addr, sizeof(struct in6_addr), sid); addr, sizeof(struct in6_addr), sid);
new->nsec.addr.ipv6 = *(struct in6_addr *)addr; new->nsec.addr.ipv6 = *(struct in6_addr *)addr;
break; break;
......
...@@ -161,7 +161,7 @@ static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid) ...@@ -161,7 +161,7 @@ static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid)
new = kzalloc(sizeof(*new), GFP_ATOMIC); new = kzalloc(sizeof(*new), GFP_ATOMIC);
if (new == NULL) if (new == NULL)
goto out; goto out;
ret = security_port_sid(protocol, pnum, sid); ret = security_port_sid(&selinux_state, protocol, pnum, sid);
if (ret != 0) if (ret != 0)
goto out; goto out;
......
This diff is collapsed.
...@@ -655,7 +655,8 @@ int avtab_write(struct policydb *p, struct avtab *a, void *fp) ...@@ -655,7 +655,8 @@ int avtab_write(struct policydb *p, struct avtab *a, void *fp)
return rc; return rc;
} }
void avtab_cache_init(void)
void __init avtab_cache_init(void)
{ {
avtab_node_cachep = kmem_cache_create("avtab_node", avtab_node_cachep = kmem_cache_create("avtab_node",
sizeof(struct avtab_node), sizeof(struct avtab_node),
...@@ -664,9 +665,3 @@ void avtab_cache_init(void) ...@@ -664,9 +665,3 @@ void avtab_cache_init(void)
sizeof(struct avtab_extended_perms), sizeof(struct avtab_extended_perms),
0, SLAB_PANIC, NULL); 0, SLAB_PANIC, NULL);
} }
void avtab_cache_destroy(void)
{
kmem_cache_destroy(avtab_node_cachep);
kmem_cache_destroy(avtab_xperms_cachep);
}
...@@ -114,9 +114,6 @@ struct avtab_node *avtab_search_node(struct avtab *h, struct avtab_key *key); ...@@ -114,9 +114,6 @@ struct avtab_node *avtab_search_node(struct avtab *h, struct avtab_key *key);
struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified); struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified);
void avtab_cache_init(void);
void avtab_cache_destroy(void);
#define MAX_AVTAB_HASH_BITS 16 #define MAX_AVTAB_HASH_BITS 16
#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) #define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)
......
...@@ -523,14 +523,9 @@ int ebitmap_write(struct ebitmap *e, void *fp) ...@@ -523,14 +523,9 @@ int ebitmap_write(struct ebitmap *e, void *fp)
return 0; return 0;
} }
void ebitmap_cache_init(void) void __init ebitmap_cache_init(void)
{ {
ebitmap_node_cachep = kmem_cache_create("ebitmap_node", ebitmap_node_cachep = kmem_cache_create("ebitmap_node",
sizeof(struct ebitmap_node), sizeof(struct ebitmap_node),
0, SLAB_PANIC, NULL); 0, SLAB_PANIC, NULL);
} }
void ebitmap_cache_destroy(void)
{
kmem_cache_destroy(ebitmap_node_cachep);
}
...@@ -131,9 +131,6 @@ void ebitmap_destroy(struct ebitmap *e); ...@@ -131,9 +131,6 @@ void ebitmap_destroy(struct ebitmap *e);
int ebitmap_read(struct ebitmap *e, void *fp); int ebitmap_read(struct ebitmap *e, void *fp);
int ebitmap_write(struct ebitmap *e, void *fp); int ebitmap_write(struct ebitmap *e, void *fp);
void ebitmap_cache_init(void);
void ebitmap_cache_destroy(void);
#ifdef CONFIG_NETLABEL #ifdef CONFIG_NETLABEL
int ebitmap_netlbl_export(struct ebitmap *ebmap, int ebitmap_netlbl_export(struct ebitmap *ebmap,
struct netlbl_lsm_catmap **catmap); struct netlbl_lsm_catmap **catmap);
......
...@@ -169,14 +169,10 @@ void hashtab_stat(struct hashtab *h, struct hashtab_info *info) ...@@ -169,14 +169,10 @@ void hashtab_stat(struct hashtab *h, struct hashtab_info *info)
info->slots_used = slots_used; info->slots_used = slots_used;
info->max_chain_len = max_chain_len; info->max_chain_len = max_chain_len;
} }
void hashtab_cache_init(void)
void __init hashtab_cache_init(void)
{ {
hashtab_node_cachep = kmem_cache_create("hashtab_node", hashtab_node_cachep = kmem_cache_create("hashtab_node",
sizeof(struct hashtab_node), sizeof(struct hashtab_node),
0, SLAB_PANIC, NULL); 0, SLAB_PANIC, NULL);
} }
void hashtab_cache_destroy(void)
{
kmem_cache_destroy(hashtab_node_cachep);
}
...@@ -85,8 +85,4 @@ int hashtab_map(struct hashtab *h, ...@@ -85,8 +85,4 @@ int hashtab_map(struct hashtab *h,
/* Fill info with some hash table statistics */ /* Fill info with some hash table statistics */
void hashtab_stat(struct hashtab *h, struct hashtab_info *info); void hashtab_stat(struct hashtab *h, struct hashtab_info *info);
/* Use kmem_cache for hashtab_node */
void hashtab_cache_init(void);
void hashtab_cache_destroy(void);
#endif /* _SS_HASHTAB_H */ #endif /* _SS_HASHTAB_H */
...@@ -33,20 +33,20 @@ ...@@ -33,20 +33,20 @@
* Return the length in bytes for the MLS fields of the * Return the length in bytes for the MLS fields of the
* security context string representation of `context'. * security context string representation of `context'.
*/ */
int mls_compute_context_len(struct context *context) int mls_compute_context_len(struct policydb *p, struct context *context)
{ {
int i, l, len, head, prev; int i, l, len, head, prev;
char *nm; char *nm;
struct ebitmap *e; struct ebitmap *e;
struct ebitmap_node *node; struct ebitmap_node *node;
if (!policydb.mls_enabled) if (!p->mls_enabled)
return 0; return 0;
len = 1; /* for the beginning ":" */ len = 1; /* for the beginning ":" */
for (l = 0; l < 2; l++) { for (l = 0; l < 2; l++) {
int index_sens = context->range.level[l].sens; int index_sens = context->range.level[l].sens;
len += strlen(sym_name(&policydb, SYM_LEVELS, index_sens - 1)); len += strlen(sym_name(p, SYM_LEVELS, index_sens - 1));
/* categories */ /* categories */
head = -2; head = -2;
...@@ -56,17 +56,17 @@ int mls_compute_context_len(struct context *context) ...@@ -56,17 +56,17 @@ int mls_compute_context_len(struct context *context)
if (i - prev > 1) { if (i - prev > 1) {
/* one or more negative bits are skipped */ /* one or more negative bits are skipped */
if (head != prev) { if (head != prev) {
nm = sym_name(&policydb, SYM_CATS, prev); nm = sym_name(p, SYM_CATS, prev);
len += strlen(nm) + 1; len += strlen(nm) + 1;
} }
nm = sym_name(&policydb, SYM_CATS, i); nm = sym_name(p, SYM_CATS, i);
len += strlen(nm) + 1; len += strlen(nm) + 1;
head = i; head = i;
} }
prev = i; prev = i;
} }
if (prev != head) { if (prev != head) {
nm = sym_name(&policydb, SYM_CATS, prev); nm = sym_name(p, SYM_CATS, prev);
len += strlen(nm) + 1; len += strlen(nm) + 1;
} }
if (l == 0) { if (l == 0) {
...@@ -86,7 +86,8 @@ int mls_compute_context_len(struct context *context) ...@@ -86,7 +86,8 @@ int mls_compute_context_len(struct context *context)
* the MLS fields of `context' into the string `*scontext'. * the MLS fields of `context' into the string `*scontext'.
* Update `*scontext' to point to the end of the MLS fields. * Update `*scontext' to point to the end of the MLS fields.
*/ */
void mls_sid_to_context(struct context *context, void mls_sid_to_context(struct policydb *p,
struct context *context,
char **scontext) char **scontext)
{ {
char *scontextp, *nm; char *scontextp, *nm;
...@@ -94,7 +95,7 @@ void mls_sid_to_context(struct context *context, ...@@ -94,7 +95,7 @@ void mls_sid_to_context(struct context *context,
struct ebitmap *e; struct ebitmap *e;
struct ebitmap_node *node; struct ebitmap_node *node;
if (!policydb.mls_enabled) if (!p->mls_enabled)
return; return;
scontextp = *scontext; scontextp = *scontext;
...@@ -103,7 +104,7 @@ void mls_sid_to_context(struct context *context, ...@@ -103,7 +104,7 @@ void mls_sid_to_context(struct context *context,
scontextp++; scontextp++;
for (l = 0; l < 2; l++) { for (l = 0; l < 2; l++) {
strcpy(scontextp, sym_name(&policydb, SYM_LEVELS, strcpy(scontextp, sym_name(p, SYM_LEVELS,
context->range.level[l].sens - 1)); context->range.level[l].sens - 1));
scontextp += strlen(scontextp); scontextp += strlen(scontextp);
...@@ -119,7 +120,7 @@ void mls_sid_to_context(struct context *context, ...@@ -119,7 +120,7 @@ void mls_sid_to_context(struct context *context,
*scontextp++ = '.'; *scontextp++ = '.';
else else
*scontextp++ = ','; *scontextp++ = ',';
nm = sym_name(&policydb, SYM_CATS, prev); nm = sym_name(p, SYM_CATS, prev);
strcpy(scontextp, nm); strcpy(scontextp, nm);
scontextp += strlen(nm); scontextp += strlen(nm);
} }
...@@ -127,7 +128,7 @@ void mls_sid_to_context(struct context *context, ...@@ -127,7 +128,7 @@ void mls_sid_to_context(struct context *context,
*scontextp++ = ':'; *scontextp++ = ':';
else else
*scontextp++ = ','; *scontextp++ = ',';
nm = sym_name(&policydb, SYM_CATS, i); nm = sym_name(p, SYM_CATS, i);
strcpy(scontextp, nm); strcpy(scontextp, nm);
scontextp += strlen(nm); scontextp += strlen(nm);
head = i; head = i;
...@@ -140,7 +141,7 @@ void mls_sid_to_context(struct context *context, ...@@ -140,7 +141,7 @@ void mls_sid_to_context(struct context *context,
*scontextp++ = '.'; *scontextp++ = '.';
else else
*scontextp++ = ','; *scontextp++ = ',';
nm = sym_name(&policydb, SYM_CATS, prev); nm = sym_name(p, SYM_CATS, prev);
strcpy(scontextp, nm); strcpy(scontextp, nm);
scontextp += strlen(nm); scontextp += strlen(nm);
} }
...@@ -375,12 +376,13 @@ int mls_context_to_sid(struct policydb *pol, ...@@ -375,12 +376,13 @@ int mls_context_to_sid(struct policydb *pol,
* the string `str'. This function will allocate temporary memory with the * the string `str'. This function will allocate temporary memory with the
* given constraints of gfp_mask. * given constraints of gfp_mask.
*/ */
int mls_from_string(char *str, struct context *context, gfp_t gfp_mask) int mls_from_string(struct policydb *p, char *str, struct context *context,
gfp_t gfp_mask)
{ {
char *tmpstr, *freestr; char *tmpstr, *freestr;
int rc; int rc;
if (!policydb.mls_enabled) if (!p->mls_enabled)
return -EINVAL; return -EINVAL;
/* we need freestr because mls_context_to_sid will change /* we need freestr because mls_context_to_sid will change
...@@ -389,7 +391,7 @@ int mls_from_string(char *str, struct context *context, gfp_t gfp_mask) ...@@ -389,7 +391,7 @@ int mls_from_string(char *str, struct context *context, gfp_t gfp_mask)
if (!tmpstr) { if (!tmpstr) {
rc = -ENOMEM; rc = -ENOMEM;
} else { } else {
rc = mls_context_to_sid(&policydb, ':', &tmpstr, context, rc = mls_context_to_sid(p, ':', &tmpstr, context,
NULL, SECSID_NULL); NULL, SECSID_NULL);
kfree(freestr); kfree(freestr);
} }
...@@ -417,10 +419,11 @@ int mls_range_set(struct context *context, ...@@ -417,10 +419,11 @@ int mls_range_set(struct context *context,
return rc; return rc;
} }
int mls_setup_user_range(struct context *fromcon, struct user_datum *user, int mls_setup_user_range(struct policydb *p,
struct context *fromcon, struct user_datum *user,
struct context *usercon) struct context *usercon)
{ {
if (policydb.mls_enabled) { if (p->mls_enabled) {
struct mls_level *fromcon_sen = &(fromcon->range.level[0]); struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
struct mls_level *fromcon_clr = &(fromcon->range.level[1]); struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
struct mls_level *user_low = &(user->range.level[0]); struct mls_level *user_low = &(user->range.level[0]);
...@@ -470,7 +473,7 @@ int mls_convert_context(struct policydb *oldp, ...@@ -470,7 +473,7 @@ int mls_convert_context(struct policydb *oldp,
struct ebitmap_node *node; struct ebitmap_node *node;
int l, i; int l, i;
if (!policydb.mls_enabled) if (!oldp->mls_enabled || !newp->mls_enabled)
return 0; return 0;
for (l = 0; l < 2; l++) { for (l = 0; l < 2; l++) {
...@@ -503,7 +506,8 @@ int mls_convert_context(struct policydb *oldp, ...@@ -503,7 +506,8 @@ int mls_convert_context(struct policydb *oldp,
return 0; return 0;
} }
int mls_compute_sid(struct context *scontext, int mls_compute_sid(struct policydb *p,
struct context *scontext,
struct context *tcontext, struct context *tcontext,
u16 tclass, u16 tclass,
u32 specified, u32 specified,
...@@ -515,7 +519,7 @@ int mls_compute_sid(struct context *scontext, ...@@ -515,7 +519,7 @@ int mls_compute_sid(struct context *scontext,
struct class_datum *cladatum; struct class_datum *cladatum;
int default_range = 0; int default_range = 0;
if (!policydb.mls_enabled) if (!p->mls_enabled)
return 0; return 0;
switch (specified) { switch (specified) {
...@@ -524,12 +528,12 @@ int mls_compute_sid(struct context *scontext, ...@@ -524,12 +528,12 @@ int mls_compute_sid(struct context *scontext,
rtr.source_type = scontext->type; rtr.source_type = scontext->type;
rtr.target_type = tcontext->type; rtr.target_type = tcontext->type;
rtr.target_class = tclass; rtr.target_class = tclass;
r = hashtab_search(policydb.range_tr, &rtr); r = hashtab_search(p->range_tr, &rtr);
if (r) if (r)
return mls_range_set(newcontext, r); return mls_range_set(newcontext, r);
if (tclass && tclass <= policydb.p_classes.nprim) { if (tclass && tclass <= p->p_classes.nprim) {
cladatum = policydb.class_val_to_struct[tclass - 1]; cladatum = p->class_val_to_struct[tclass - 1];
if (cladatum) if (cladatum)
default_range = cladatum->default_range; default_range = cladatum->default_range;
} }
...@@ -551,7 +555,7 @@ int mls_compute_sid(struct context *scontext, ...@@ -551,7 +555,7 @@ int mls_compute_sid(struct context *scontext,
/* Fallthrough */ /* Fallthrough */
case AVTAB_CHANGE: case AVTAB_CHANGE:
if ((tclass == policydb.process_class) || (sock == true)) if ((tclass == p->process_class) || (sock == true))
/* Use the process MLS attributes. */ /* Use the process MLS attributes. */
return mls_context_cpy(newcontext, scontext); return mls_context_cpy(newcontext, scontext);
else else
...@@ -577,10 +581,11 @@ int mls_compute_sid(struct context *scontext, ...@@ -577,10 +581,11 @@ int mls_compute_sid(struct context *scontext,
* NetLabel MLS sensitivity level field. * NetLabel MLS sensitivity level field.
* *
*/ */
void mls_export_netlbl_lvl(struct context *context, void mls_export_netlbl_lvl(struct policydb *p,
struct context *context,
struct netlbl_lsm_secattr *secattr) struct netlbl_lsm_secattr *secattr)
{ {
if (!policydb.mls_enabled) if (!p->mls_enabled)
return; return;
secattr->attr.mls.lvl = context->range.level[0].sens - 1; secattr->attr.mls.lvl = context->range.level[0].sens - 1;
...@@ -597,10 +602,11 @@ void mls_export_netlbl_lvl(struct context *context, ...@@ -597,10 +602,11 @@ void mls_export_netlbl_lvl(struct context *context,
* NetLabel MLS sensitivity level into the context. * NetLabel MLS sensitivity level into the context.
* *
*/ */
void mls_import_netlbl_lvl(struct context *context, void mls_import_netlbl_lvl(struct policydb *p,
struct context *context,
struct netlbl_lsm_secattr *secattr) struct netlbl_lsm_secattr *secattr)
{ {
if (!policydb.mls_enabled) if (!p->mls_enabled)
return; return;
context->range.level[0].sens = secattr->attr.mls.lvl + 1; context->range.level[0].sens = secattr->attr.mls.lvl + 1;
...@@ -617,12 +623,13 @@ void mls_import_netlbl_lvl(struct context *context, ...@@ -617,12 +623,13 @@ void mls_import_netlbl_lvl(struct context *context,
* MLS category field. Returns zero on success, negative values on failure. * MLS category field. Returns zero on success, negative values on failure.
* *
*/ */
int mls_export_netlbl_cat(struct context *context, int mls_export_netlbl_cat(struct policydb *p,
struct context *context,
struct netlbl_lsm_secattr *secattr) struct netlbl_lsm_secattr *secattr)
{ {
int rc; int rc;
if (!policydb.mls_enabled) if (!p->mls_enabled)
return 0; return 0;
rc = ebitmap_netlbl_export(&context->range.level[0].cat, rc = ebitmap_netlbl_export(&context->range.level[0].cat,
...@@ -645,12 +652,13 @@ int mls_export_netlbl_cat(struct context *context, ...@@ -645,12 +652,13 @@ int mls_export_netlbl_cat(struct context *context,
* negative values on failure. * negative values on failure.
* *
*/ */
int mls_import_netlbl_cat(struct context *context, int mls_import_netlbl_cat(struct policydb *p,
struct context *context,
struct netlbl_lsm_secattr *secattr) struct netlbl_lsm_secattr *secattr)
{ {
int rc; int rc;
if (!policydb.mls_enabled) if (!p->mls_enabled)
return 0; return 0;
rc = ebitmap_netlbl_import(&context->range.level[0].cat, rc = ebitmap_netlbl_import(&context->range.level[0].cat,
......
...@@ -25,8 +25,9 @@ ...@@ -25,8 +25,9 @@
#include "context.h" #include "context.h"
#include "policydb.h" #include "policydb.h"
int mls_compute_context_len(struct context *context); int mls_compute_context_len(struct policydb *p, struct context *context);
void mls_sid_to_context(struct context *context, char **scontext); void mls_sid_to_context(struct policydb *p, struct context *context,
char **scontext);
int mls_context_isvalid(struct policydb *p, struct context *c); int mls_context_isvalid(struct policydb *p, struct context *c);
int mls_range_isvalid(struct policydb *p, struct mls_range *r); int mls_range_isvalid(struct policydb *p, struct mls_range *r);
int mls_level_isvalid(struct policydb *p, struct mls_level *l); int mls_level_isvalid(struct policydb *p, struct mls_level *l);
...@@ -38,7 +39,8 @@ int mls_context_to_sid(struct policydb *p, ...@@ -38,7 +39,8 @@ int mls_context_to_sid(struct policydb *p,
struct sidtab *s, struct sidtab *s,
u32 def_sid); u32 def_sid);
int mls_from_string(char *str, struct context *context, gfp_t gfp_mask); int mls_from_string(struct policydb *p, char *str, struct context *context,
gfp_t gfp_mask);
int mls_range_set(struct context *context, struct mls_range *range); int mls_range_set(struct context *context, struct mls_range *range);
...@@ -46,42 +48,52 @@ int mls_convert_context(struct policydb *oldp, ...@@ -46,42 +48,52 @@ int mls_convert_context(struct policydb *oldp,
struct policydb *newp, struct policydb *newp,
struct context *context); struct context *context);
int mls_compute_sid(struct context *scontext, int mls_compute_sid(struct policydb *p,
struct context *scontext,
struct context *tcontext, struct context *tcontext,
u16 tclass, u16 tclass,
u32 specified, u32 specified,
struct context *newcontext, struct context *newcontext,
bool sock); bool sock);
int mls_setup_user_range(struct context *fromcon, struct user_datum *user, int mls_setup_user_range(struct policydb *p,
struct context *fromcon, struct user_datum *user,
struct context *usercon); struct context *usercon);
#ifdef CONFIG_NETLABEL #ifdef CONFIG_NETLABEL
void mls_export_netlbl_lvl(struct context *context, void mls_export_netlbl_lvl(struct policydb *p,
struct context *context,
struct netlbl_lsm_secattr *secattr); struct netlbl_lsm_secattr *secattr);
void mls_import_netlbl_lvl(struct context *context, void mls_import_netlbl_lvl(struct policydb *p,
struct context *context,
struct netlbl_lsm_secattr *secattr); struct netlbl_lsm_secattr *secattr);
int mls_export_netlbl_cat(struct context *context, int mls_export_netlbl_cat(struct policydb *p,
struct context *context,
struct netlbl_lsm_secattr *secattr); struct netlbl_lsm_secattr *secattr);
int mls_import_netlbl_cat(struct context *context, int mls_import_netlbl_cat(struct policydb *p,
struct context *context,
struct netlbl_lsm_secattr *secattr); struct netlbl_lsm_secattr *secattr);
#else #else
static inline void mls_export_netlbl_lvl(struct context *context, static inline void mls_export_netlbl_lvl(struct policydb *p,
struct context *context,
struct netlbl_lsm_secattr *secattr) struct netlbl_lsm_secattr *secattr)
{ {
return; return;
} }
static inline void mls_import_netlbl_lvl(struct context *context, static inline void mls_import_netlbl_lvl(struct policydb *p,
struct context *context,
struct netlbl_lsm_secattr *secattr) struct netlbl_lsm_secattr *secattr)
{ {
return; return;
} }
static inline int mls_export_netlbl_cat(struct context *context, static inline int mls_export_netlbl_cat(struct policydb *p,
struct context *context,
struct netlbl_lsm_secattr *secattr) struct netlbl_lsm_secattr *secattr)
{ {
return -ENOMEM; return -ENOMEM;
} }
static inline int mls_import_netlbl_cat(struct context *context, static inline int mls_import_netlbl_cat(struct policydb *p,
struct context *context,
struct netlbl_lsm_secattr *secattr) struct netlbl_lsm_secattr *secattr)
{ {
return -ENOMEM; return -ENOMEM;
......
This diff is collapsed.
...@@ -10,7 +10,28 @@ ...@@ -10,7 +10,28 @@
#include "policydb.h" #include "policydb.h"
#include "sidtab.h" #include "sidtab.h"
extern struct policydb policydb; /* Mapping for a single class */
struct selinux_mapping {
u16 value; /* policy value for class */
unsigned int num_perms; /* number of permissions in class */
u32 perms[sizeof(u32) * 8]; /* policy values for permissions */
};
/* Map for all of the classes, with array size */
struct selinux_map {
struct selinux_mapping *mapping; /* indexed by class */
u16 size; /* array size of mapping */
};
struct selinux_ss {
struct sidtab sidtab;
struct policydb policydb;
rwlock_t policy_rwlock;
u32 latest_granting;
struct selinux_map map;
struct page *status_page;
struct mutex status_lock;
};
void services_compute_xperms_drivers(struct extended_perms *xperms, void services_compute_xperms_drivers(struct extended_perms *xperms,
struct avtab_node *node); struct avtab_node *node);
...@@ -19,4 +40,3 @@ void services_compute_xperms_decision(struct extended_perms_decision *xpermd, ...@@ -19,4 +40,3 @@ void services_compute_xperms_decision(struct extended_perms_decision *xpermd,
struct avtab_node *node); struct avtab_node *node);
#endif /* _SS_SERVICES_H_ */ #endif /* _SS_SERVICES_H_ */
...@@ -35,8 +35,6 @@ ...@@ -35,8 +35,6 @@
* In most cases, application shall confirm the kernel status is not * In most cases, application shall confirm the kernel status is not
* changed without any system call invocations. * changed without any system call invocations.
*/ */
static struct page *selinux_status_page;
static DEFINE_MUTEX(selinux_status_lock);
/* /*
* selinux_kernel_status_page * selinux_kernel_status_page
...@@ -44,21 +42,21 @@ static DEFINE_MUTEX(selinux_status_lock); ...@@ -44,21 +42,21 @@ static DEFINE_MUTEX(selinux_status_lock);
* It returns a reference to selinux_status_page. If the status page is * It returns a reference to selinux_status_page. If the status page is
* not allocated yet, it also tries to allocate it at the first time. * not allocated yet, it also tries to allocate it at the first time.
*/ */
struct page *selinux_kernel_status_page(void) struct page *selinux_kernel_status_page(struct selinux_state *state)
{ {
struct selinux_kernel_status *status; struct selinux_kernel_status *status;
struct page *result = NULL; struct page *result = NULL;
mutex_lock(&selinux_status_lock); mutex_lock(&state->ss->status_lock);
if (!selinux_status_page) { if (!state->ss->status_page) {
selinux_status_page = alloc_page(GFP_KERNEL|__GFP_ZERO); state->ss->status_page = alloc_page(GFP_KERNEL|__GFP_ZERO);
if (selinux_status_page) { if (state->ss->status_page) {
status = page_address(selinux_status_page); status = page_address(state->ss->status_page);
status->version = SELINUX_KERNEL_STATUS_VERSION; status->version = SELINUX_KERNEL_STATUS_VERSION;
status->sequence = 0; status->sequence = 0;
status->enforcing = selinux_enforcing; status->enforcing = is_enforcing(state);
/* /*
* NOTE: the next policyload event shall set * NOTE: the next policyload event shall set
* a positive value on the status->policyload, * a positive value on the status->policyload,
...@@ -66,11 +64,12 @@ struct page *selinux_kernel_status_page(void) ...@@ -66,11 +64,12 @@ struct page *selinux_kernel_status_page(void)
* So, application can know it was updated. * So, application can know it was updated.
*/ */
status->policyload = 0; status->policyload = 0;
status->deny_unknown = !security_get_allow_unknown(); status->deny_unknown =
!security_get_allow_unknown(state);
} }
} }
result = selinux_status_page; result = state->ss->status_page;
mutex_unlock(&selinux_status_lock); mutex_unlock(&state->ss->status_lock);
return result; return result;
} }
...@@ -80,13 +79,14 @@ struct page *selinux_kernel_status_page(void) ...@@ -80,13 +79,14 @@ struct page *selinux_kernel_status_page(void)
* *
* It updates status of the current enforcing/permissive mode. * It updates status of the current enforcing/permissive mode.
*/ */
void selinux_status_update_setenforce(int enforcing) void selinux_status_update_setenforce(struct selinux_state *state,
int enforcing)
{ {
struct selinux_kernel_status *status; struct selinux_kernel_status *status;
mutex_lock(&selinux_status_lock); mutex_lock(&state->ss->status_lock);
if (selinux_status_page) { if (state->ss->status_page) {
status = page_address(selinux_status_page); status = page_address(state->ss->status_page);
status->sequence++; status->sequence++;
smp_wmb(); smp_wmb();
...@@ -96,7 +96,7 @@ void selinux_status_update_setenforce(int enforcing) ...@@ -96,7 +96,7 @@ void selinux_status_update_setenforce(int enforcing)
smp_wmb(); smp_wmb();
status->sequence++; status->sequence++;
} }
mutex_unlock(&selinux_status_lock); mutex_unlock(&state->ss->status_lock);
} }
/* /*
...@@ -105,22 +105,23 @@ void selinux_status_update_setenforce(int enforcing) ...@@ -105,22 +105,23 @@ void selinux_status_update_setenforce(int enforcing)
* It updates status of the times of policy reloaded, and current * It updates status of the times of policy reloaded, and current
* setting of deny_unknown. * setting of deny_unknown.
*/ */
void selinux_status_update_policyload(int seqno) void selinux_status_update_policyload(struct selinux_state *state,
int seqno)
{ {
struct selinux_kernel_status *status; struct selinux_kernel_status *status;
mutex_lock(&selinux_status_lock); mutex_lock(&state->ss->status_lock);
if (selinux_status_page) { if (state->ss->status_page) {
status = page_address(selinux_status_page); status = page_address(state->ss->status_page);
status->sequence++; status->sequence++;
smp_wmb(); smp_wmb();
status->policyload = seqno; status->policyload = seqno;
status->deny_unknown = !security_get_allow_unknown(); status->deny_unknown = !security_get_allow_unknown(state);
smp_wmb(); smp_wmb();
status->sequence++; status->sequence++;
} }
mutex_unlock(&selinux_status_lock); mutex_unlock(&state->ss->status_lock);
} }
...@@ -101,7 +101,8 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp, ...@@ -101,7 +101,8 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
ctx->ctx_len = str_len; ctx->ctx_len = str_len;
memcpy(ctx->ctx_str, &uctx[1], str_len); memcpy(ctx->ctx_str, &uctx[1], str_len);
ctx->ctx_str[str_len] = '\0'; ctx->ctx_str[str_len] = '\0';
rc = security_context_to_sid(ctx->ctx_str, str_len, &ctx->ctx_sid, gfp); rc = security_context_to_sid(&selinux_state, ctx->ctx_str, str_len,
&ctx->ctx_sid, gfp);
if (rc) if (rc)
goto err; goto err;
...@@ -352,7 +353,8 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x, ...@@ -352,7 +353,8 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
if (secid == 0) if (secid == 0)
return -EINVAL; return -EINVAL;
rc = security_sid_to_context(secid, &ctx_str, &str_len); rc = security_sid_to_context(&selinux_state, secid, &ctx_str,
&str_len);
if (rc) if (rc)
return rc; return rc;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment