Smack: Use the netlabel cache
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 <casey@schaufler-ca.com>
This commit is contained in:
parent
a2af031885
commit
322dd63c7f
|
@ -297,6 +297,7 @@ struct smack_known *smk_find_entry(const char *);
|
||||||
bool smack_privileged(int cap);
|
bool smack_privileged(int cap);
|
||||||
bool smack_privileged_cred(int cap, const struct cred *cred);
|
bool smack_privileged_cred(int cap, const struct cred *cred);
|
||||||
void smk_destroy_label_list(struct list_head *list);
|
void smk_destroy_label_list(struct list_head *list);
|
||||||
|
int smack_populate_secattr(struct smack_known *skp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Shared data.
|
* Shared data.
|
||||||
|
|
|
@ -510,6 +510,42 @@ int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap,
|
||||||
return 0;
|
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
|
* smk_import_entry - import a label, return the list entry
|
||||||
* @string: a text string that might be a Smack label
|
* @string: a text string that might be a Smack label
|
||||||
|
@ -523,7 +559,6 @@ struct smack_known *smk_import_entry(const char *string, int len)
|
||||||
{
|
{
|
||||||
struct smack_known *skp;
|
struct smack_known *skp;
|
||||||
char *smack;
|
char *smack;
|
||||||
int slen;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
smack = smk_parse_smack(string, len);
|
smack = smk_parse_smack(string, len);
|
||||||
|
@ -544,21 +579,8 @@ struct smack_known *smk_import_entry(const char *string, int len)
|
||||||
|
|
||||||
skp->smk_known = smack;
|
skp->smk_known = smack;
|
||||||
skp->smk_secid = smack_next_secid++;
|
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) {
|
if (rc >= 0) {
|
||||||
INIT_LIST_HEAD(&skp->smk_rules);
|
INIT_LIST_HEAD(&skp->smk_rules);
|
||||||
mutex_init(&skp->smk_rules_lock);
|
mutex_init(&skp->smk_rules_lock);
|
||||||
|
@ -569,9 +591,6 @@ struct smack_known *smk_import_entry(const char *string, int len)
|
||||||
smk_insert_entry(skp);
|
smk_insert_entry(skp);
|
||||||
goto unlockout;
|
goto unlockout;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* smk_netlbl_mls failed.
|
|
||||||
*/
|
|
||||||
kfree(skp);
|
kfree(skp);
|
||||||
skp = ERR_PTR(rc);
|
skp = ERR_PTR(rc);
|
||||||
freeout:
|
freeout:
|
||||||
|
|
|
@ -3715,6 +3715,18 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
|
||||||
int acat;
|
int acat;
|
||||||
int kcat;
|
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) {
|
if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
|
||||||
/*
|
/*
|
||||||
* Looks like a CIPSO packet.
|
* Looks like a CIPSO packet.
|
||||||
|
@ -3762,11 +3774,6 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
|
||||||
return &smack_known_web;
|
return &smack_known_web;
|
||||||
return &smack_known_star;
|
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
|
* Without guidance regarding the smack value
|
||||||
* for the packet fall back on the network
|
* for the packet fall back on the network
|
||||||
|
@ -3845,6 +3852,9 @@ static struct smack_known *smack_from_skb(struct sk_buff *skb)
|
||||||
* @family: address family
|
* @family: address family
|
||||||
* @skb: packet
|
* @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.
|
* 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,
|
static struct smack_known *smack_from_netlbl(struct sock *sk, u16 family,
|
||||||
|
@ -3853,13 +3863,18 @@ static struct smack_known *smack_from_netlbl(struct sock *sk, u16 family,
|
||||||
struct netlbl_lsm_secattr secattr;
|
struct netlbl_lsm_secattr secattr;
|
||||||
struct socket_smack *ssp = NULL;
|
struct socket_smack *ssp = NULL;
|
||||||
struct smack_known *skp = NULL;
|
struct smack_known *skp = NULL;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
netlbl_secattr_init(&secattr);
|
netlbl_secattr_init(&secattr);
|
||||||
|
|
||||||
if (sk)
|
if (sk)
|
||||||
ssp = sk->sk_security;
|
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);
|
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);
|
netlbl_secattr_destroy(&secattr);
|
||||||
|
|
||||||
|
|
|
@ -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.cat = ncats.attr.mls.cat;
|
||||||
skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl;
|
skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl;
|
||||||
rc = count;
|
rc = count;
|
||||||
|
/*
|
||||||
|
* This mapping may have been cached, so clear the cache.
|
||||||
|
*/
|
||||||
|
netlbl_cache_invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -2950,15 +2954,6 @@ static struct file_system_type smk_fs_type = {
|
||||||
|
|
||||||
static struct vfsmount *smackfs_mount;
|
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
|
* init_smk_fs - get the smackfs superblock
|
||||||
*
|
*
|
||||||
|
@ -2997,19 +2992,19 @@ static int __init init_smk_fs(void)
|
||||||
smk_cipso_doi();
|
smk_cipso_doi();
|
||||||
smk_unlbl_ambient(NULL);
|
smk_unlbl_ambient(NULL);
|
||||||
|
|
||||||
rc = smk_preset_netlabel(&smack_known_floor);
|
rc = smack_populate_secattr(&smack_known_floor);
|
||||||
if (err == 0 && rc < 0)
|
if (err == 0 && rc < 0)
|
||||||
err = rc;
|
err = rc;
|
||||||
rc = smk_preset_netlabel(&smack_known_hat);
|
rc = smack_populate_secattr(&smack_known_hat);
|
||||||
if (err == 0 && rc < 0)
|
if (err == 0 && rc < 0)
|
||||||
err = rc;
|
err = rc;
|
||||||
rc = smk_preset_netlabel(&smack_known_huh);
|
rc = smack_populate_secattr(&smack_known_huh);
|
||||||
if (err == 0 && rc < 0)
|
if (err == 0 && rc < 0)
|
||||||
err = rc;
|
err = rc;
|
||||||
rc = smk_preset_netlabel(&smack_known_star);
|
rc = smack_populate_secattr(&smack_known_star);
|
||||||
if (err == 0 && rc < 0)
|
if (err == 0 && rc < 0)
|
||||||
err = rc;
|
err = rc;
|
||||||
rc = smk_preset_netlabel(&smack_known_web);
|
rc = smack_populate_secattr(&smack_known_web);
|
||||||
if (err == 0 && rc < 0)
|
if (err == 0 && rc < 0)
|
||||||
err = rc;
|
err = rc;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue