Skip to content

Commit

Permalink
Smack: Use the netlabel cache
Browse files Browse the repository at this point in the history
Utilize the Netlabel cache mechanism for incoming packet matching.
Refactor the initialization of secattr structures, as it was being
done in two places.

Signed-off-by: Casey Schaufler <[email protected]>
  • Loading branch information
cschaufler authored and Casey Schaufler committed Sep 11, 2020
1 parent a2af031 commit 322dd63
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 38 deletions.
1 change: 1 addition & 0 deletions security/smack/smack.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ struct smack_known *smk_find_entry(const char *);
bool smack_privileged(int cap);
bool smack_privileged_cred(int cap, const struct cred *cred);
void smk_destroy_label_list(struct list_head *list);
int smack_populate_secattr(struct smack_known *skp);

/*
* Shared data.
Expand Down
55 changes: 37 additions & 18 deletions security/smack/smack_access.c
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,42 @@ int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap,
return 0;
}

/**
* smack_populate_secattr - fill in the smack_known netlabel information
* @skp: pointer to the structure to fill
*
* Populate the netlabel secattr structure for a Smack label.
*
* Returns 0 unless creating the category mapping fails
*/
int smack_populate_secattr(struct smack_known *skp)
{
int slen;

skp->smk_netlabel.attr.secid = skp->smk_secid;
skp->smk_netlabel.domain = skp->smk_known;
skp->smk_netlabel.cache = netlbl_secattr_cache_alloc(GFP_ATOMIC);
if (skp->smk_netlabel.cache != NULL) {
skp->smk_netlabel.flags |= NETLBL_SECATTR_CACHE;
skp->smk_netlabel.cache->free = NULL;
skp->smk_netlabel.cache->data = skp;
}
skp->smk_netlabel.flags |= NETLBL_SECATTR_SECID |
NETLBL_SECATTR_MLS_LVL |
NETLBL_SECATTR_DOMAIN;
/*
* If direct labeling works use it.
* Otherwise use mapped labeling.
*/
slen = strlen(skp->smk_known);
if (slen < SMK_CIPSOLEN)
return smk_netlbl_mls(smack_cipso_direct, skp->smk_known,
&skp->smk_netlabel, slen);

return smk_netlbl_mls(smack_cipso_mapped, (char *)&skp->smk_secid,
&skp->smk_netlabel, sizeof(skp->smk_secid));
}

/**
* smk_import_entry - import a label, return the list entry
* @string: a text string that might be a Smack label
Expand All @@ -523,7 +559,6 @@ struct smack_known *smk_import_entry(const char *string, int len)
{
struct smack_known *skp;
char *smack;
int slen;
int rc;

smack = smk_parse_smack(string, len);
Expand All @@ -544,21 +579,8 @@ struct smack_known *smk_import_entry(const char *string, int len)

skp->smk_known = smack;
skp->smk_secid = smack_next_secid++;
skp->smk_netlabel.domain = skp->smk_known;
skp->smk_netlabel.flags =
NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL;
/*
* If direct labeling works use it.
* Otherwise use mapped labeling.
*/
slen = strlen(smack);
if (slen < SMK_CIPSOLEN)
rc = smk_netlbl_mls(smack_cipso_direct, skp->smk_known,
&skp->smk_netlabel, slen);
else
rc = smk_netlbl_mls(smack_cipso_mapped, (char *)&skp->smk_secid,
&skp->smk_netlabel, sizeof(skp->smk_secid));

rc = smack_populate_secattr(skp);
if (rc >= 0) {
INIT_LIST_HEAD(&skp->smk_rules);
mutex_init(&skp->smk_rules_lock);
Expand All @@ -569,9 +591,6 @@ struct smack_known *smk_import_entry(const char *string, int len)
smk_insert_entry(skp);
goto unlockout;
}
/*
* smk_netlbl_mls failed.
*/
kfree(skp);
skp = ERR_PTR(rc);
freeout:
Expand Down
27 changes: 21 additions & 6 deletions security/smack/smack_lsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -3715,6 +3715,18 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
int acat;
int kcat;

/*
* Netlabel found it in the cache.
*/
if ((sap->flags & NETLBL_SECATTR_CACHE) != 0)
return (struct smack_known *)sap->cache->data;

if ((sap->flags & NETLBL_SECATTR_SECID) != 0)
/*
* Looks like a fallback, which gives us a secid.
*/
return smack_from_secid(sap->attr.secid);

if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
/*
* Looks like a CIPSO packet.
Expand Down Expand Up @@ -3762,11 +3774,6 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
return &smack_known_web;
return &smack_known_star;
}
if ((sap->flags & NETLBL_SECATTR_SECID) != 0)
/*
* Looks like a fallback, which gives us a secid.
*/
return smack_from_secid(sap->attr.secid);
/*
* Without guidance regarding the smack value
* for the packet fall back on the network
Expand Down Expand Up @@ -3845,6 +3852,9 @@ static struct smack_known *smack_from_skb(struct sk_buff *skb)
* @family: address family
* @skb: packet
*
* Find the Smack label in the IP options. If it hasn't been
* added to the netlabel cache, add it here.
*
* Returns smack_known of the IP options or NULL if that won't work.
*/
static struct smack_known *smack_from_netlbl(struct sock *sk, u16 family,
Expand All @@ -3853,13 +3863,18 @@ static struct smack_known *smack_from_netlbl(struct sock *sk, u16 family,
struct netlbl_lsm_secattr secattr;
struct socket_smack *ssp = NULL;
struct smack_known *skp = NULL;
int rc = 0;

netlbl_secattr_init(&secattr);

if (sk)
ssp = sk->sk_security;
if (netlbl_skbuff_getattr(skb, family, &secattr) == 0)

if (netlbl_skbuff_getattr(skb, family, &secattr) == 0) {
skp = smack_from_secattr(&secattr, ssp);
if (secattr.flags & NETLBL_SECATTR_CACHEABLE)
rc = netlbl_cache_add(skb, family, &skp->smk_netlabel);
}

netlbl_secattr_destroy(&secattr);

Expand Down
23 changes: 9 additions & 14 deletions security/smack/smackfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,10 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat;
skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl;
rc = count;
/*
* This mapping may have been cached, so clear the cache.
*/
netlbl_cache_invalidate();
}

out:
Expand Down Expand Up @@ -2950,15 +2954,6 @@ static struct file_system_type smk_fs_type = {

static struct vfsmount *smackfs_mount;

static int __init smk_preset_netlabel(struct smack_known *skp)
{
skp->smk_netlabel.domain = skp->smk_known;
skp->smk_netlabel.flags =
NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL;
return smk_netlbl_mls(smack_cipso_direct, skp->smk_known,
&skp->smk_netlabel, strlen(skp->smk_known));
}

/**
* init_smk_fs - get the smackfs superblock
*
Expand Down Expand Up @@ -2997,19 +2992,19 @@ static int __init init_smk_fs(void)
smk_cipso_doi();
smk_unlbl_ambient(NULL);

rc = smk_preset_netlabel(&smack_known_floor);
rc = smack_populate_secattr(&smack_known_floor);
if (err == 0 && rc < 0)
err = rc;
rc = smk_preset_netlabel(&smack_known_hat);
rc = smack_populate_secattr(&smack_known_hat);
if (err == 0 && rc < 0)
err = rc;
rc = smk_preset_netlabel(&smack_known_huh);
rc = smack_populate_secattr(&smack_known_huh);
if (err == 0 && rc < 0)
err = rc;
rc = smk_preset_netlabel(&smack_known_star);
rc = smack_populate_secattr(&smack_known_star);
if (err == 0 && rc < 0)
err = rc;
rc = smk_preset_netlabel(&smack_known_web);
rc = smack_populate_secattr(&smack_known_web);
if (err == 0 && rc < 0)
err = rc;

Expand Down

0 comments on commit 322dd63

Please sign in to comment.