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

selinux: stop passing selinux_state pointers and their offspring

Linus observed that the pervasive passing of selinux_state pointers
introduced by me in commit aa8e712c ("selinux: wrap global selinux
state") adds overhead and complexity without providing any
benefit. The original idea was to pave the way for SELinux namespaces
but those have not yet been implemented and there isn't currently
a concrete plan to do so. Remove the passing of the selinux_state
pointers, reverting to direct use of the single global selinux_state,
and likewise remove passing of child pointers like the selinux_avc.
The selinux_policy pointer remains as it is needed for atomic switching
of policies.
Suggested-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Reported-by: default avatarkernel test robot <lkp@intel.com>
Link: https://lore.kernel.org/oe-kbuild-all/202303101057.mZ3Gv5fK-lkp@intel.com/Signed-off-by: default avatarStephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
parent f62ca0b6
This diff is collapsed.
This diff is collapsed.
......@@ -141,7 +141,7 @@ static int sel_ib_pkey_sid_slow(u64 subnet_prefix, u16 pkey_num, u32 *sid)
return 0;
}
ret = security_ib_pkey_sid(&selinux_state, subnet_prefix, pkey_num,
ret = security_ib_pkey_sid(subnet_prefix, pkey_num,
sid);
if (ret)
goto out;
......
......@@ -15,12 +15,10 @@
/*
* selinux_ima_collect_state - Read selinux configuration settings
*
* @state: selinux_state
*
* On success returns the configuration settings string.
* On error, returns NULL.
*/
static char *selinux_ima_collect_state(struct selinux_state *state)
static char *selinux_ima_collect_state(void)
{
const char *on = "=1;", *off = "=0;";
char *buf;
......@@ -39,26 +37,27 @@ static char *selinux_ima_collect_state(struct selinux_state *state)
rc = strscpy(buf, "initialized", buf_len);
WARN_ON(rc < 0);
rc = strlcat(buf, selinux_initialized(state) ? on : off, buf_len);
rc = strlcat(buf, selinux_initialized() ? on : off, buf_len);
WARN_ON(rc >= buf_len);
rc = strlcat(buf, "enforcing", buf_len);
WARN_ON(rc >= buf_len);
rc = strlcat(buf, enforcing_enabled(state) ? on : off, buf_len);
rc = strlcat(buf, enforcing_enabled() ? on : off, buf_len);
WARN_ON(rc >= buf_len);
rc = strlcat(buf, "checkreqprot", buf_len);
WARN_ON(rc >= buf_len);
rc = strlcat(buf, checkreqprot_get(state) ? on : off, buf_len);
rc = strlcat(buf, checkreqprot_get() ? on : off, buf_len);
WARN_ON(rc >= buf_len);
for (i = 0; i < __POLICYDB_CAP_MAX; i++) {
rc = strlcat(buf, selinux_policycap_names[i], buf_len);
WARN_ON(rc >= buf_len);
rc = strlcat(buf, state->policycap[i] ? on : off, buf_len);
rc = strlcat(buf, selinux_state.policycap[i] ? on : off,
buf_len);
WARN_ON(rc >= buf_len);
}
......@@ -67,19 +66,17 @@ static char *selinux_ima_collect_state(struct selinux_state *state)
/*
* selinux_ima_measure_state_locked - Measure SELinux state and hash of policy
*
* @state: selinux state struct
*/
void selinux_ima_measure_state_locked(struct selinux_state *state)
void selinux_ima_measure_state_locked(void)
{
char *state_str = NULL;
void *policy = NULL;
size_t policy_len;
int rc = 0;
lockdep_assert_held(&state->policy_mutex);
lockdep_assert_held(&selinux_state.policy_mutex);
state_str = selinux_ima_collect_state(state);
state_str = selinux_ima_collect_state();
if (!state_str) {
pr_err("SELinux: %s: failed to read state.\n", __func__);
return;
......@@ -94,10 +91,10 @@ void selinux_ima_measure_state_locked(struct selinux_state *state)
/*
* Measure SELinux policy only after initialization is completed.
*/
if (!selinux_initialized(state))
if (!selinux_initialized())
return;
rc = security_read_state_kernel(state, &policy, &policy_len);
rc = security_read_state_kernel(&policy, &policy_len);
if (rc) {
pr_err("SELinux: %s: failed to read policy %d.\n", __func__, rc);
return;
......@@ -112,14 +109,12 @@ void selinux_ima_measure_state_locked(struct selinux_state *state)
/*
* selinux_ima_measure_state - Measure SELinux state and hash of policy
*
* @state: selinux state struct
*/
void selinux_ima_measure_state(struct selinux_state *state)
void selinux_ima_measure_state(void)
{
lockdep_assert_not_held(&state->policy_mutex);
lockdep_assert_not_held(&selinux_state.policy_mutex);
mutex_lock(&state->policy_mutex);
selinux_ima_measure_state_locked(state);
mutex_unlock(&state->policy_mutex);
mutex_lock(&selinux_state.policy_mutex);
selinux_ima_measure_state_locked();
mutex_unlock(&selinux_state.policy_mutex);
}
......@@ -52,7 +52,6 @@ struct selinux_audit_data {
u32 audited;
u32 denied;
int result;
struct selinux_state *state;
} __randomize_layout;
/*
......@@ -97,14 +96,12 @@ static inline u32 avc_audit_required(u32 requested,
return audited;
}
int slow_avc_audit(struct selinux_state *state,
u32 ssid, u32 tsid, u16 tclass,
int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
u32 requested, u32 audited, u32 denied, int result,
struct common_audit_data *a);
/**
* avc_audit - Audit the granting or denial of permissions.
* @state: SELinux state
* @ssid: source security identifier
* @tsid: target security identifier
* @tclass: target security class
......@@ -122,8 +119,7 @@ int slow_avc_audit(struct selinux_state *state,
* be performed under a lock, to allow the lock to be released
* before calling the auditing code.
*/
static inline int avc_audit(struct selinux_state *state,
u32 ssid, u32 tsid,
static inline int avc_audit(u32 ssid, u32 tsid,
u16 tclass, u32 requested,
struct av_decision *avd,
int result,
......@@ -133,30 +129,27 @@ static inline int avc_audit(struct selinux_state *state,
audited = avc_audit_required(requested, avd, result, 0, &denied);
if (likely(!audited))
return 0;
return slow_avc_audit(state, ssid, tsid, tclass,
return slow_avc_audit(ssid, tsid, tclass,
requested, audited, denied, result,
a);
}
#define AVC_STRICT 1 /* Ignore permissive mode. */
#define AVC_EXTENDED_PERMS 2 /* update extended permissions */
int avc_has_perm_noaudit(struct selinux_state *state,
u32 ssid, u32 tsid,
int avc_has_perm_noaudit(u32 ssid, u32 tsid,
u16 tclass, u32 requested,
unsigned flags,
struct av_decision *avd);
int avc_has_perm(struct selinux_state *state,
u32 ssid, u32 tsid,
int avc_has_perm(u32 ssid, u32 tsid,
u16 tclass, u32 requested,
struct common_audit_data *auditdata);
int avc_has_extended_perms(struct selinux_state *state,
u32 ssid, u32 tsid, u16 tclass, u32 requested,
int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested,
u8 driver, u8 perm, struct common_audit_data *ad);
u32 avc_policy_seqno(struct selinux_state *state);
u32 avc_policy_seqno(void);
#define AVC_CALLBACK_GRANT 1
#define AVC_CALLBACK_TRY_REVOKE 2
......@@ -171,11 +164,9 @@ u32 avc_policy_seqno(struct selinux_state *state);
int avc_add_callback(int (*callback)(u32 event), u32 events);
/* Exported to selinuxfs */
struct selinux_avc;
int avc_get_hash_stats(struct selinux_avc *avc, char *page);
unsigned int avc_get_cache_threshold(struct selinux_avc *avc);
void avc_set_cache_threshold(struct selinux_avc *avc,
unsigned int cache_threshold);
int avc_get_hash_stats(char *page);
unsigned int avc_get_cache_threshold(void);
void avc_set_cache_threshold(unsigned int cache_threshold);
/* Attempt to free avc node cache */
void avc_disable(void);
......
......@@ -9,8 +9,7 @@
#include <linux/types.h>
struct selinux_avc;
int avc_ss_reset(struct selinux_avc *avc, u32 seqno);
int avc_ss_reset(u32 seqno);
/* Class/perm mapping support */
struct security_class_mapping {
......
......@@ -16,8 +16,8 @@
int security_get_bools(struct selinux_policy *policy,
u32 *len, char ***names, int **values);
int security_set_bools(struct selinux_state *state, u32 len, int *values);
int security_set_bools(u32 len, int *values);
int security_get_bool_value(struct selinux_state *state, u32 index);
int security_get_bool_value(u32 index);
#endif
......@@ -14,15 +14,13 @@
#include "security.h"
#ifdef CONFIG_IMA
extern void selinux_ima_measure_state(struct selinux_state *selinux_state);
extern void selinux_ima_measure_state_locked(
struct selinux_state *selinux_state);
extern void selinux_ima_measure_state(void);
extern void selinux_ima_measure_state_locked(void);
#else
static inline void selinux_ima_measure_state(struct selinux_state *selinux_state)
static inline void selinux_ima_measure_state(void)
{
}
static inline void selinux_ima_measure_state_locked(
struct selinux_state *selinux_state)
static inline void selinux_ima_measure_state_locked(void)
{
}
#endif
......
This diff is collapsed.
......@@ -153,7 +153,7 @@ static int sel_netif_sid_slow(struct net *ns, int ifindex, u32 *sid)
goto out;
}
ret = security_netif_sid(&selinux_state, dev->name, sid);
ret = security_netif_sid(dev->name, sid);
if (ret != 0)
goto out;
new = kzalloc(sizeof(*new), GFP_ATOMIC);
......
......@@ -46,7 +46,7 @@ static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,
{
int rc;
rc = security_netlbl_secattr_to_sid(&selinux_state, secattr, sid);
rc = security_netlbl_secattr_to_sid(secattr, sid);
if (rc == 0 &&
(secattr->flags & NETLBL_SECATTR_CACHEABLE) &&
(secattr->flags & NETLBL_SECATTR_CACHE))
......@@ -77,8 +77,7 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk)
secattr = netlbl_secattr_alloc(GFP_ATOMIC);
if (secattr == NULL)
return NULL;
rc = security_netlbl_sid_to_secattr(&selinux_state, sksec->sid,
secattr);
rc = security_netlbl_sid_to_secattr(sksec->sid, secattr);
if (rc != 0) {
netlbl_secattr_free(secattr);
return NULL;
......@@ -245,8 +244,7 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
if (secattr == NULL) {
secattr = &secattr_storage;
netlbl_secattr_init(secattr);
rc = security_netlbl_sid_to_secattr(&selinux_state, sid,
secattr);
rc = security_netlbl_sid_to_secattr(sid, secattr);
if (rc != 0)
goto skbuff_setsid_return;
}
......@@ -283,8 +281,7 @@ int selinux_netlbl_sctp_assoc_request(struct sctp_association *asoc,
return 0;
netlbl_secattr_init(&secattr);
rc = security_netlbl_sid_to_secattr(&selinux_state,
asoc->secid, &secattr);
rc = security_netlbl_sid_to_secattr(asoc->secid, &secattr);
if (rc != 0)
goto assoc_request_return;
......@@ -332,8 +329,7 @@ int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family)
return 0;
netlbl_secattr_init(&secattr);
rc = security_netlbl_sid_to_secattr(&selinux_state, req->secid,
&secattr);
rc = security_netlbl_sid_to_secattr(req->secid, &secattr);
if (rc != 0)
goto inet_conn_request_return;
rc = netlbl_req_setattr(req, &secattr);
......@@ -463,8 +459,7 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
perm = RAWIP_SOCKET__RECVFROM;
}
rc = avc_has_perm(&selinux_state,
sksec->sid, nlbl_sid, sksec->sclass, perm, ad);
rc = avc_has_perm(sksec->sid, nlbl_sid, sksec->sclass, perm, ad);
if (rc == 0)
return 0;
......
......@@ -204,13 +204,13 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
new = kzalloc(sizeof(*new), GFP_ATOMIC);
switch (family) {
case PF_INET:
ret = security_node_sid(&selinux_state, PF_INET,
ret = security_node_sid(PF_INET,
addr, sizeof(struct in_addr), sid);
if (new)
new->nsec.addr.ipv4 = *(__be32 *)addr;
break;
case PF_INET6:
ret = security_node_sid(&selinux_state, PF_INET6,
ret = security_node_sid(PF_INET6,
addr, sizeof(struct in6_addr), sid);
if (new)
new->nsec.addr.ipv6 = *(struct in6_addr *)addr;
......
......@@ -148,7 +148,7 @@ static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid)
return 0;
}
ret = security_port_sid(&selinux_state, protocol, pnum, sid);
ret = security_port_sid(protocol, pnum, sid);
if (ret != 0)
goto out;
new = kzalloc(sizeof(*new), GFP_ATOMIC);
......
This diff is collapsed.
This diff is collapsed.
......@@ -30,7 +30,6 @@ struct selinux_policy {
} __randomize_layout;
struct convert_context_args {
struct selinux_state *state;
struct policydb *oldp;
struct policydb *newp;
};
......
......@@ -39,21 +39,21 @@
* 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.
*/
struct page *selinux_kernel_status_page(struct selinux_state *state)
struct page *selinux_kernel_status_page(void)
{
struct selinux_kernel_status *status;
struct page *result = NULL;
mutex_lock(&state->status_lock);
if (!state->status_page) {
state->status_page = alloc_page(GFP_KERNEL|__GFP_ZERO);
mutex_lock(&selinux_state.status_lock);
if (!selinux_state.status_page) {
selinux_state.status_page = alloc_page(GFP_KERNEL|__GFP_ZERO);
if (state->status_page) {
status = page_address(state->status_page);
if (selinux_state.status_page) {
status = page_address(selinux_state.status_page);
status->version = SELINUX_KERNEL_STATUS_VERSION;
status->sequence = 0;
status->enforcing = enforcing_enabled(state);
status->enforcing = enforcing_enabled();
/*
* NOTE: the next policyload event shall set
* a positive value on the status->policyload,
......@@ -62,11 +62,11 @@ struct page *selinux_kernel_status_page(struct selinux_state *state)
*/
status->policyload = 0;
status->deny_unknown =
!security_get_allow_unknown(state);
!security_get_allow_unknown();
}
}
result = state->status_page;
mutex_unlock(&state->status_lock);
result = selinux_state.status_page;
mutex_unlock(&selinux_state.status_lock);
return result;
}
......@@ -76,14 +76,13 @@ struct page *selinux_kernel_status_page(struct selinux_state *state)
*
* It updates status of the current enforcing/permissive mode.
*/
void selinux_status_update_setenforce(struct selinux_state *state,
int enforcing)
void selinux_status_update_setenforce(int enforcing)
{
struct selinux_kernel_status *status;
mutex_lock(&state->status_lock);
if (state->status_page) {
status = page_address(state->status_page);
mutex_lock(&selinux_state.status_lock);
if (selinux_state.status_page) {
status = page_address(selinux_state.status_page);
status->sequence++;
smp_wmb();
......@@ -93,7 +92,7 @@ void selinux_status_update_setenforce(struct selinux_state *state,
smp_wmb();
status->sequence++;
}
mutex_unlock(&state->status_lock);
mutex_unlock(&selinux_state.status_lock);
}
/*
......@@ -102,23 +101,22 @@ void selinux_status_update_setenforce(struct selinux_state *state,
* It updates status of the times of policy reloaded, and current
* setting of deny_unknown.
*/
void selinux_status_update_policyload(struct selinux_state *state,
int seqno)
void selinux_status_update_policyload(int seqno)
{
struct selinux_kernel_status *status;
mutex_lock(&state->status_lock);
if (state->status_page) {
status = page_address(state->status_page);
mutex_lock(&selinux_state.status_lock);
if (selinux_state.status_page) {
status = page_address(selinux_state.status_page);
status->sequence++;
smp_wmb();
status->policyload = seqno;
status->deny_unknown = !security_get_allow_unknown(state);
status->deny_unknown = !security_get_allow_unknown();
smp_wmb();
status->sequence++;
}
mutex_unlock(&state->status_lock);
mutex_unlock(&selinux_state.status_lock);
}
......@@ -98,13 +98,12 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
ctx->ctx_len = str_len;
memcpy(ctx->ctx_str, &uctx[1], str_len);
ctx->ctx_str[str_len] = '\0';
rc = security_context_to_sid(&selinux_state, ctx->ctx_str, str_len,
rc = security_context_to_sid(ctx->ctx_str, str_len,
&ctx->ctx_sid, gfp);
if (rc)
goto err;
rc = avc_has_perm(&selinux_state,
tsec->sid, ctx->ctx_sid,
rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, NULL);
if (rc)
goto err;
......@@ -140,8 +139,7 @@ static int selinux_xfrm_delete(struct xfrm_sec_ctx *ctx)
if (!ctx)
return 0;
return avc_has_perm(&selinux_state,
tsec->sid, ctx->ctx_sid,
return avc_has_perm(tsec->sid, ctx->ctx_sid,
SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT,
NULL);
}
......@@ -163,8 +161,7 @@ int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid)
if (!selinux_authorizable_ctx(ctx))
return -EINVAL;
rc = avc_has_perm(&selinux_state,
fl_secid, ctx->ctx_sid,
rc = avc_has_perm(fl_secid, ctx->ctx_sid,
SECCLASS_ASSOCIATION, ASSOCIATION__POLMATCH, NULL);
return (rc == -EACCES ? -ESRCH : rc);
}
......@@ -205,7 +202,7 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
/* We don't need a separate SA Vs. policy polmatch check since the SA
* is now of the same label as the flow and a flow Vs. policy polmatch
* check had already happened in selinux_xfrm_policy_lookup() above. */
return (avc_has_perm(&selinux_state, flic_sid, state_sid,
return (avc_has_perm(flic_sid, state_sid,
SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO,
NULL) ? 0 : 1);
}
......@@ -355,7 +352,7 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
if (secid == 0)
return -EINVAL;
rc = security_sid_to_context(&selinux_state, secid, &ctx_str,
rc = security_sid_to_context(secid, &ctx_str,
&str_len);
if (rc)
return rc;
......@@ -424,8 +421,7 @@ int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb,
/* This check even when there's no association involved is intended,
* according to Trent Jaeger, to make sure a process can't engage in
* non-IPsec communication unless explicitly allowed by policy. */
return avc_has_perm(&selinux_state,
sk_sid, peer_sid,
return avc_has_perm(sk_sid, peer_sid,
SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, ad);
}
......@@ -468,6 +464,6 @@ int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb,
/* This check even when there's no association involved is intended,
* according to Trent Jaeger, to make sure a process can't engage in
* non-IPsec communication unless explicitly allowed by policy. */
return avc_has_perm(&selinux_state, sk_sid, SECINITSID_UNLABELED,
return avc_has_perm(sk_sid, SECINITSID_UNLABELED,
SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, ad);
}
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