Skip to content

Commit

Permalink
selinux: use separate table for initial SID lookup
Browse files Browse the repository at this point in the history
This moves handling of initial SIDs into a separate table. Note that the
SIDs stored in the main table are now shifted by SECINITSID_NUM and
converted to/from the actual SIDs transparently by helper functions.

This change doesn't make much sense on its own, but it simplifies
further sidtab overhaul in a succeeding patch.

Signed-off-by: Ondrej Mosnacek <[email protected]>
Reviewed-by: Stephen Smalley <[email protected]>
[PM: fixed some checkpatch warnings on line length, whitespace]
Signed-off-by: Paul Moore <[email protected]>
  • Loading branch information
WOnder93 authored and pcmoore committed Dec 5, 2018
1 parent 89f5beb commit 24ed7fd
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 110 deletions.
10 changes: 9 additions & 1 deletion security/selinux/ss/policydb.c
Original file line number Diff line number Diff line change
Expand Up @@ -909,13 +909,21 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s)
if (!c->context[0].user) {
pr_err("SELinux: SID %s was never defined.\n",
c->u.name);
sidtab_destroy(s);
goto out;
}
if (c->sid[0] == SECSID_NULL || c->sid[0] > SECINITSID_NUM) {
pr_err("SELinux: Initial SID %s out of range.\n",
c->u.name);
sidtab_destroy(s);
goto out;
}

rc = sidtab_insert(s, c->sid[0], &c->context[0]);
rc = sidtab_set_initial(s, c->sid[0], &c->context[0]);
if (rc) {
pr_err("SELinux: unable to load initial SID %s.\n",
c->u.name);
sidtab_destroy(s);
goto out;
}
}
Expand Down
88 changes: 50 additions & 38 deletions security/selinux/ss/services.c
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ static int security_compute_validatetrans(struct selinux_state *state,
read_lock(&state->ss->policy_rwlock);

policydb = &state->ss->policydb;
sidtab = &state->ss->sidtab;
sidtab = state->ss->sidtab;

if (!user)
tclass = unmap_class(&state->ss->map, orig_tclass);
Expand Down Expand Up @@ -876,7 +876,7 @@ int security_bounded_transition(struct selinux_state *state,
read_lock(&state->ss->policy_rwlock);

policydb = &state->ss->policydb;
sidtab = &state->ss->sidtab;
sidtab = state->ss->sidtab;

rc = -EINVAL;
old_context = sidtab_search(sidtab, old_sid);
Expand Down Expand Up @@ -1034,7 +1034,7 @@ void security_compute_xperms_decision(struct selinux_state *state,
goto allow;

policydb = &state->ss->policydb;
sidtab = &state->ss->sidtab;
sidtab = state->ss->sidtab;

scontext = sidtab_search(sidtab, ssid);
if (!scontext) {
Expand Down Expand Up @@ -1123,7 +1123,7 @@ void security_compute_av(struct selinux_state *state,
goto allow;

policydb = &state->ss->policydb;
sidtab = &state->ss->sidtab;
sidtab = state->ss->sidtab;

scontext = sidtab_search(sidtab, ssid);
if (!scontext) {
Expand Down Expand Up @@ -1177,7 +1177,7 @@ void security_compute_av_user(struct selinux_state *state,
goto allow;

policydb = &state->ss->policydb;
sidtab = &state->ss->sidtab;
sidtab = state->ss->sidtab;

scontext = sidtab_search(sidtab, ssid);
if (!scontext) {
Expand Down Expand Up @@ -1315,7 +1315,7 @@ static int security_sid_to_context_core(struct selinux_state *state,
}
read_lock(&state->ss->policy_rwlock);
policydb = &state->ss->policydb;
sidtab = &state->ss->sidtab;
sidtab = state->ss->sidtab;
if (force)
context = sidtab_search_force(sidtab, sid);
else
Expand Down Expand Up @@ -1483,7 +1483,7 @@ static int security_context_to_sid_core(struct selinux_state *state,
}
read_lock(&state->ss->policy_rwlock);
policydb = &state->ss->policydb;
sidtab = &state->ss->sidtab;
sidtab = state->ss->sidtab;
rc = string_to_context_struct(policydb, sidtab, scontext2,
&context, def_sid);
if (rc == -EINVAL && force) {
Expand Down Expand Up @@ -1668,7 +1668,7 @@ static int security_compute_sid(struct selinux_state *state,
}

policydb = &state->ss->policydb;
sidtab = &state->ss->sidtab;
sidtab = state->ss->sidtab;

scontext = sidtab_search(sidtab, ssid);
if (!scontext) {
Expand Down Expand Up @@ -1925,10 +1925,7 @@ static int convert_context(u32 key,
struct user_datum *usrdatum;
char *s;
u32 len;
int rc = 0;

if (key <= SECINITSID_NUM)
goto out;
int rc;

args = p;

Expand Down Expand Up @@ -2090,9 +2087,8 @@ static int security_preserve_bools(struct selinux_state *state,
int security_load_policy(struct selinux_state *state, void *data, size_t len)
{
struct policydb *policydb;
struct sidtab *sidtab;
struct sidtab *oldsidtab, *newsidtab;
struct policydb *oldpolicydb, *newpolicydb;
struct sidtab oldsidtab, newsidtab;
struct selinux_mapping *oldmapping;
struct selinux_map newmap;
struct convert_context_args args;
Expand All @@ -2108,27 +2104,37 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len)
newpolicydb = oldpolicydb + 1;

policydb = &state->ss->policydb;
sidtab = &state->ss->sidtab;

newsidtab = kmalloc(sizeof(*newsidtab), GFP_KERNEL);
if (!newsidtab) {
rc = -ENOMEM;
goto out;
}

if (!state->initialized) {
rc = policydb_read(policydb, fp);
if (rc)
if (rc) {
kfree(newsidtab);
goto out;
}

policydb->len = len;
rc = selinux_set_mapping(policydb, secclass_map,
&state->ss->map);
if (rc) {
kfree(newsidtab);
policydb_destroy(policydb);
goto out;
}

rc = policydb_load_isids(policydb, sidtab);
rc = policydb_load_isids(policydb, newsidtab);
if (rc) {
kfree(newsidtab);
policydb_destroy(policydb);
goto out;
}

state->ss->sidtab = newsidtab;
security_load_policycaps(state);
state->initialized = 1;
seqno = ++state->ss->latest_granting;
Expand All @@ -2141,13 +2147,17 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len)
goto out;
}

oldsidtab = state->ss->sidtab;

#if 0
sidtab_hash_eval(sidtab, "sids");
sidtab_hash_eval(oldsidtab, "sids");
#endif

rc = policydb_read(newpolicydb, fp);
if (rc)
if (rc) {
kfree(newsidtab);
goto out;
}

newpolicydb->len = len;
/* If switching between different policy types, log MLS status */
Expand All @@ -2156,10 +2166,11 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len)
else if (!policydb->mls_enabled && newpolicydb->mls_enabled)
pr_info("SELinux: Enabling MLS support...\n");

rc = policydb_load_isids(newpolicydb, &newsidtab);
rc = policydb_load_isids(newpolicydb, newsidtab);
if (rc) {
pr_err("SELinux: unable to load the initial SIDs\n");
policydb_destroy(newpolicydb);
kfree(newsidtab);
goto out;
}

Expand All @@ -2180,7 +2191,7 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len)
args.state = state;
args.oldp = policydb;
args.newp = newpolicydb;
rc = sidtab_convert(sidtab, &newsidtab, convert_context, &args);
rc = sidtab_convert(oldsidtab, newsidtab, convert_context, &args);
if (rc) {
pr_err("SELinux: unable to convert the internal"
" representation of contexts in the new SID"
Expand All @@ -2190,12 +2201,11 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len)

/* Save the old policydb and SID table to free later. */
memcpy(oldpolicydb, policydb, sizeof(*policydb));
sidtab_set(&oldsidtab, sidtab);

/* Install the new policydb and SID table. */
write_lock_irq(&state->ss->policy_rwlock);
memcpy(policydb, newpolicydb, sizeof(*policydb));
sidtab_set(sidtab, &newsidtab);
state->ss->sidtab = newsidtab;
security_load_policycaps(state);
oldmapping = state->ss->map.mapping;
state->ss->map.mapping = newmap.mapping;
Expand All @@ -2205,7 +2215,8 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len)

/* Free the old policydb and SID table. */
policydb_destroy(oldpolicydb);
sidtab_destroy(&oldsidtab);
sidtab_destroy(oldsidtab);
kfree(oldsidtab);
kfree(oldmapping);

avc_ss_reset(state->avc, seqno);
Expand All @@ -2219,7 +2230,8 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len)

err:
kfree(newmap.mapping);
sidtab_destroy(&newsidtab);
sidtab_destroy(newsidtab);
kfree(newsidtab);
policydb_destroy(newpolicydb);

out:
Expand Down Expand Up @@ -2256,7 +2268,7 @@ int security_port_sid(struct selinux_state *state,
read_lock(&state->ss->policy_rwlock);

policydb = &state->ss->policydb;
sidtab = &state->ss->sidtab;
sidtab = state->ss->sidtab;

c = policydb->ocontexts[OCON_PORT];
while (c) {
Expand Down Expand Up @@ -2302,7 +2314,7 @@ int security_ib_pkey_sid(struct selinux_state *state,
read_lock(&state->ss->policy_rwlock);

policydb = &state->ss->policydb;
sidtab = &state->ss->sidtab;
sidtab = state->ss->sidtab;

c = policydb->ocontexts[OCON_IBPKEY];
while (c) {
Expand Down Expand Up @@ -2348,7 +2360,7 @@ int security_ib_endport_sid(struct selinux_state *state,
read_lock(&state->ss->policy_rwlock);

policydb = &state->ss->policydb;
sidtab = &state->ss->sidtab;
sidtab = state->ss->sidtab;

c = policydb->ocontexts[OCON_IBENDPORT];
while (c) {
Expand Down Expand Up @@ -2394,7 +2406,7 @@ int security_netif_sid(struct selinux_state *state,
read_lock(&state->ss->policy_rwlock);

policydb = &state->ss->policydb;
sidtab = &state->ss->sidtab;
sidtab = state->ss->sidtab;

c = policydb->ocontexts[OCON_NETIF];
while (c) {
Expand Down Expand Up @@ -2459,7 +2471,7 @@ int security_node_sid(struct selinux_state *state,
read_lock(&state->ss->policy_rwlock);

policydb = &state->ss->policydb;
sidtab = &state->ss->sidtab;
sidtab = state->ss->sidtab;

switch (domain) {
case AF_INET: {
Expand Down Expand Up @@ -2559,7 +2571,7 @@ int security_get_user_sids(struct selinux_state *state,
read_lock(&state->ss->policy_rwlock);

policydb = &state->ss->policydb;
sidtab = &state->ss->sidtab;
sidtab = state->ss->sidtab;

context_init(&usercon);

Expand Down Expand Up @@ -2661,7 +2673,7 @@ static inline int __security_genfs_sid(struct selinux_state *state,
u32 *sid)
{
struct policydb *policydb = &state->ss->policydb;
struct sidtab *sidtab = &state->ss->sidtab;
struct sidtab *sidtab = state->ss->sidtab;
int len;
u16 sclass;
struct genfs *genfs;
Expand Down Expand Up @@ -2747,7 +2759,7 @@ int security_fs_use(struct selinux_state *state, struct super_block *sb)
read_lock(&state->ss->policy_rwlock);

policydb = &state->ss->policydb;
sidtab = &state->ss->sidtab;
sidtab = state->ss->sidtab;

c = policydb->ocontexts[OCON_FSUSE];
while (c) {
Expand Down Expand Up @@ -2953,7 +2965,7 @@ int security_sid_mls_copy(struct selinux_state *state,
u32 sid, u32 mls_sid, u32 *new_sid)
{
struct policydb *policydb = &state->ss->policydb;
struct sidtab *sidtab = &state->ss->sidtab;
struct sidtab *sidtab = state->ss->sidtab;
struct context *context1;
struct context *context2;
struct context newcon;
Expand Down Expand Up @@ -3044,7 +3056,7 @@ int security_net_peersid_resolve(struct selinux_state *state,
u32 *peer_sid)
{
struct policydb *policydb = &state->ss->policydb;
struct sidtab *sidtab = &state->ss->sidtab;
struct sidtab *sidtab = state->ss->sidtab;
int rc;
struct context *nlbl_ctx;
struct context *xfrm_ctx;
Expand Down Expand Up @@ -3405,7 +3417,7 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
goto out;
}

ctxt = sidtab_search(&state->ss->sidtab, sid);
ctxt = sidtab_search(state->ss->sidtab, sid);
if (unlikely(!ctxt)) {
WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n",
sid);
Expand Down Expand Up @@ -3568,7 +3580,7 @@ int security_netlbl_secattr_to_sid(struct selinux_state *state,
u32 *sid)
{
struct policydb *policydb = &state->ss->policydb;
struct sidtab *sidtab = &state->ss->sidtab;
struct sidtab *sidtab = state->ss->sidtab;
int rc;
struct context *ctx;
struct context ctx_new;
Expand Down Expand Up @@ -3646,7 +3658,7 @@ int security_netlbl_sid_to_secattr(struct selinux_state *state,
read_lock(&state->ss->policy_rwlock);

rc = -ENOENT;
ctx = sidtab_search(&state->ss->sidtab, sid);
ctx = sidtab_search(state->ss->sidtab, sid);
if (ctx == NULL)
goto out;

Expand Down
2 changes: 1 addition & 1 deletion security/selinux/ss/services.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct selinux_map {
};

struct selinux_ss {
struct sidtab sidtab;
struct sidtab *sidtab;
struct policydb policydb;
rwlock_t policy_rwlock;
u32 latest_granting;
Expand Down
Loading

0 comments on commit 24ed7fd

Please sign in to comment.