Skip to content

Commit 322dd63

Browse files
cschauflerCasey Schaufler
authored andcommitted
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>
1 parent a2af031 commit 322dd63

4 files changed

Lines changed: 68 additions & 38 deletions

File tree

security/smack/smack.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ struct smack_known *smk_find_entry(const char *);
297297
bool smack_privileged(int cap);
298298
bool smack_privileged_cred(int cap, const struct cred *cred);
299299
void smk_destroy_label_list(struct list_head *list);
300+
int smack_populate_secattr(struct smack_known *skp);
300301

301302
/*
302303
* Shared data.

security/smack/smack_access.c

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,42 @@ int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap,
510510
return 0;
511511
}
512512

513+
/**
514+
* smack_populate_secattr - fill in the smack_known netlabel information
515+
* @skp: pointer to the structure to fill
516+
*
517+
* Populate the netlabel secattr structure for a Smack label.
518+
*
519+
* Returns 0 unless creating the category mapping fails
520+
*/
521+
int smack_populate_secattr(struct smack_known *skp)
522+
{
523+
int slen;
524+
525+
skp->smk_netlabel.attr.secid = skp->smk_secid;
526+
skp->smk_netlabel.domain = skp->smk_known;
527+
skp->smk_netlabel.cache = netlbl_secattr_cache_alloc(GFP_ATOMIC);
528+
if (skp->smk_netlabel.cache != NULL) {
529+
skp->smk_netlabel.flags |= NETLBL_SECATTR_CACHE;
530+
skp->smk_netlabel.cache->free = NULL;
531+
skp->smk_netlabel.cache->data = skp;
532+
}
533+
skp->smk_netlabel.flags |= NETLBL_SECATTR_SECID |
534+
NETLBL_SECATTR_MLS_LVL |
535+
NETLBL_SECATTR_DOMAIN;
536+
/*
537+
* If direct labeling works use it.
538+
* Otherwise use mapped labeling.
539+
*/
540+
slen = strlen(skp->smk_known);
541+
if (slen < SMK_CIPSOLEN)
542+
return smk_netlbl_mls(smack_cipso_direct, skp->smk_known,
543+
&skp->smk_netlabel, slen);
544+
545+
return smk_netlbl_mls(smack_cipso_mapped, (char *)&skp->smk_secid,
546+
&skp->smk_netlabel, sizeof(skp->smk_secid));
547+
}
548+
513549
/**
514550
* smk_import_entry - import a label, return the list entry
515551
* @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)
523559
{
524560
struct smack_known *skp;
525561
char *smack;
526-
int slen;
527562
int rc;
528563

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

545580
skp->smk_known = smack;
546581
skp->smk_secid = smack_next_secid++;
547-
skp->smk_netlabel.domain = skp->smk_known;
548-
skp->smk_netlabel.flags =
549-
NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL;
550-
/*
551-
* If direct labeling works use it.
552-
* Otherwise use mapped labeling.
553-
*/
554-
slen = strlen(smack);
555-
if (slen < SMK_CIPSOLEN)
556-
rc = smk_netlbl_mls(smack_cipso_direct, skp->smk_known,
557-
&skp->smk_netlabel, slen);
558-
else
559-
rc = smk_netlbl_mls(smack_cipso_mapped, (char *)&skp->smk_secid,
560-
&skp->smk_netlabel, sizeof(skp->smk_secid));
561582

583+
rc = smack_populate_secattr(skp);
562584
if (rc >= 0) {
563585
INIT_LIST_HEAD(&skp->smk_rules);
564586
mutex_init(&skp->smk_rules_lock);
@@ -569,9 +591,6 @@ struct smack_known *smk_import_entry(const char *string, int len)
569591
smk_insert_entry(skp);
570592
goto unlockout;
571593
}
572-
/*
573-
* smk_netlbl_mls failed.
574-
*/
575594
kfree(skp);
576595
skp = ERR_PTR(rc);
577596
freeout:

security/smack/smack_lsm.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3715,6 +3715,18 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
37153715
int acat;
37163716
int kcat;
37173717

3718+
/*
3719+
* Netlabel found it in the cache.
3720+
*/
3721+
if ((sap->flags & NETLBL_SECATTR_CACHE) != 0)
3722+
return (struct smack_known *)sap->cache->data;
3723+
3724+
if ((sap->flags & NETLBL_SECATTR_SECID) != 0)
3725+
/*
3726+
* Looks like a fallback, which gives us a secid.
3727+
*/
3728+
return smack_from_secid(sap->attr.secid);
3729+
37183730
if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
37193731
/*
37203732
* Looks like a CIPSO packet.
@@ -3762,11 +3774,6 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
37623774
return &smack_known_web;
37633775
return &smack_known_star;
37643776
}
3765-
if ((sap->flags & NETLBL_SECATTR_SECID) != 0)
3766-
/*
3767-
* Looks like a fallback, which gives us a secid.
3768-
*/
3769-
return smack_from_secid(sap->attr.secid);
37703777
/*
37713778
* Without guidance regarding the smack value
37723779
* for the packet fall back on the network
@@ -3845,6 +3852,9 @@ static struct smack_known *smack_from_skb(struct sk_buff *skb)
38453852
* @family: address family
38463853
* @skb: packet
38473854
*
3855+
* Find the Smack label in the IP options. If it hasn't been
3856+
* added to the netlabel cache, add it here.
3857+
*
38483858
* Returns smack_known of the IP options or NULL if that won't work.
38493859
*/
38503860
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,
38533863
struct netlbl_lsm_secattr secattr;
38543864
struct socket_smack *ssp = NULL;
38553865
struct smack_known *skp = NULL;
3866+
int rc = 0;
38563867

38573868
netlbl_secattr_init(&secattr);
38583869

38593870
if (sk)
38603871
ssp = sk->sk_security;
3861-
if (netlbl_skbuff_getattr(skb, family, &secattr) == 0)
3872+
3873+
if (netlbl_skbuff_getattr(skb, family, &secattr) == 0) {
38623874
skp = smack_from_secattr(&secattr, ssp);
3875+
if (secattr.flags & NETLBL_SECATTR_CACHEABLE)
3876+
rc = netlbl_cache_add(skb, family, &skp->smk_netlabel);
3877+
}
38633878

38643879
netlbl_secattr_destroy(&secattr);
38653880

security/smack/smackfs.c

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,10 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
922922
skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat;
923923
skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl;
924924
rc = count;
925+
/*
926+
* This mapping may have been cached, so clear the cache.
927+
*/
928+
netlbl_cache_invalidate();
925929
}
926930

927931
out:
@@ -2950,15 +2954,6 @@ static struct file_system_type smk_fs_type = {
29502954

29512955
static struct vfsmount *smackfs_mount;
29522956

2953-
static int __init smk_preset_netlabel(struct smack_known *skp)
2954-
{
2955-
skp->smk_netlabel.domain = skp->smk_known;
2956-
skp->smk_netlabel.flags =
2957-
NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL;
2958-
return smk_netlbl_mls(smack_cipso_direct, skp->smk_known,
2959-
&skp->smk_netlabel, strlen(skp->smk_known));
2960-
}
2961-
29622957
/**
29632958
* init_smk_fs - get the smackfs superblock
29642959
*
@@ -2997,19 +2992,19 @@ static int __init init_smk_fs(void)
29972992
smk_cipso_doi();
29982993
smk_unlbl_ambient(NULL);
29992994

3000-
rc = smk_preset_netlabel(&smack_known_floor);
2995+
rc = smack_populate_secattr(&smack_known_floor);
30012996
if (err == 0 && rc < 0)
30022997
err = rc;
3003-
rc = smk_preset_netlabel(&smack_known_hat);
2998+
rc = smack_populate_secattr(&smack_known_hat);
30042999
if (err == 0 && rc < 0)
30053000
err = rc;
3006-
rc = smk_preset_netlabel(&smack_known_huh);
3001+
rc = smack_populate_secattr(&smack_known_huh);
30073002
if (err == 0 && rc < 0)
30083003
err = rc;
3009-
rc = smk_preset_netlabel(&smack_known_star);
3004+
rc = smack_populate_secattr(&smack_known_star);
30103005
if (err == 0 && rc < 0)
30113006
err = rc;
3012-
rc = smk_preset_netlabel(&smack_known_web);
3007+
rc = smack_populate_secattr(&smack_known_web);
30133008
if (err == 0 && rc < 0)
30143009
err = rc;
30153010

0 commit comments

Comments
 (0)