]> www.infradead.org Git - users/hch/misc.git/commitdiff
smack: recognize ipv4 CIPSO w/o categories
authorKonstantin Andreev <andreev@swemel.ru>
Thu, 16 Jan 2025 23:40:34 +0000 (02:40 +0300)
committerCasey Schaufler <casey@schaufler-ca.com>
Sun, 16 Feb 2025 22:17:55 +0000 (14:17 -0800)
If SMACK label has CIPSO representation w/o categories, e.g.:

| # cat /smack/cipso2
| foo  10
| @ 250/2
| ...

then SMACK does not recognize such CIPSO in input ipv4 packets
and substitues '*' label instead. Audit records may look like

| lsm=SMACK fn=smack_socket_sock_rcv_skb action=denied
|   subject="*" object="_" requested=w pid=0 comm="swapper/1" ...

This happens in two steps:

1) security/smack/smackfs.c`smk_set_cipso
   does not clear NETLBL_SECATTR_MLS_CAT
   from (struct smack_known *)skp->smk_netlabel.flags
   on assigning CIPSO w/o categories:

| rcu_assign_pointer(skp->smk_netlabel.attr.mls.cat, ncats.attr.mls.cat);
| skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl;

2) security/smack/smack_lsm.c`smack_from_secattr
   can not match skp->smk_netlabel with input packet's
   struct netlbl_lsm_secattr *sap
   because sap->flags have not NETLBL_SECATTR_MLS_CAT (what is correct)
   but skp->smk_netlabel.flags have (what is incorrect):

| if ((sap->flags & NETLBL_SECATTR_MLS_CAT) == 0) {
|  if ((skp->smk_netlabel.flags &
|   NETLBL_SECATTR_MLS_CAT) == 0)
|  found = 1;
|  break;
| }

This commit sets/clears NETLBL_SECATTR_MLS_CAT in
skp->smk_netlabel.flags according to the presense of CIPSO categories.
The update of smk_netlabel is not atomic, so input packets processing
still may be incorrect during short time while update proceeds.

Signed-off-by: Konstantin Andreev <andreev@swemel.ru>
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
security/smack/smackfs.c

index 2802c480521ca5145e531d74e782626ac9873d4e..90a67e410808f5d80b89bd97f48e3ee452f83048 100644 (file)
@@ -906,6 +906,10 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
        if (rc >= 0) {
                old_cat = skp->smk_netlabel.attr.mls.cat;
                rcu_assign_pointer(skp->smk_netlabel.attr.mls.cat, ncats.attr.mls.cat);
+               if (ncats.attr.mls.cat)
+                       skp->smk_netlabel.flags |= NETLBL_SECATTR_MLS_CAT;
+               else
+                       skp->smk_netlabel.flags &= ~(u32)NETLBL_SECATTR_MLS_CAT;
                skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl;
                synchronize_rcu();
                netlbl_catmap_free(old_cat);