Smack: Prevent the * and @ labels from being used in SMACK64EXEC 58/23258/1
authorCasey Schaufler <casey@schaufler-ca.com>
Tue, 17 Dec 2013 00:27:26 +0000 (16:27 -0800)
committerRafal Krypa <r.krypa@samsung.com>
Fri, 20 Jun 2014 15:17:33 +0000 (17:17 +0200)
Smack prohibits processes from using the star ("*") and web ("@") labels
because we don't want files with those labels getting created implicitly.
All setting of those labels should be done explicitly. The trouble is that
there is no check for these labels in the processing of SMACK64EXEC. That
is repaired.

Targeted for git://git.gitorious.org/smack-next/kernel.git

Change-Id: Ie95848da70efd6f5a5b7081a4bf943891396e748
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
security/smack/smack_lsm.c

index cdbf92b34e7e5e4a71da850b39b0e18f63d00a94..69b842f985a9476f8084ff22dc40f2a2e959387f 100644 (file)
@@ -835,31 +835,43 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
                                const void *value, size_t size, int flags)
 {
        struct smk_audit_info ad;
+       struct smack_known *skp;
+       int check_priv = 0;
+       int check_import = 0;
+       int check_star = 0;
        int rc = 0;
 
+       /*
+        * Check label validity here so import won't fail in post_setxattr
+        */
        if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
            strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
-           strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
-           strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
-           strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
-               if (!smack_privileged(CAP_MAC_ADMIN))
-                       rc = -EPERM;
-               /*
-                * check label validity here so import wont fail on
-                * post_setxattr
-                */
-               if (size == 0 || size >= SMK_LONGLABEL ||
-                   smk_import(value, size) == NULL)
-                       rc = -EINVAL;
+           strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
+               check_priv = 1;
+               check_import = 1;
+       } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
+                  strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
+               check_priv = 1;
+               check_import = 1;
+               check_star = 1;
        } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
-               if (!smack_privileged(CAP_MAC_ADMIN))
-                       rc = -EPERM;
+               check_priv = 1;
                if (size != TRANS_TRUE_SIZE ||
                    strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
                        rc = -EINVAL;
        } else
                rc = cap_inode_setxattr(dentry, name, value, size, flags);
 
+       if (check_priv && !smack_privileged(CAP_MAC_ADMIN))
+               rc = -EPERM;
+
+       if (rc == 0 && check_import) {
+               skp = smk_import_entry(value, size);
+               if (skp == NULL || (check_star &&
+                   (skp == &smack_known_star || skp == &smack_known_web)))
+                       rc = -EINVAL;
+       }
+
        smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
        smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
 
@@ -2851,8 +2863,17 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
                        if (rc >= 0)
                                transflag = SMK_INODE_TRANSMUTE;
                }
-               isp->smk_task = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp);
-               isp->smk_mmap = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp);
+               /*
+                * Don't let the exec or mmap label be "*" or "@".
+                */
+               skp = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp);
+               if (skp == &smack_known_star || skp == &smack_known_web)
+                       skp = NULL;
+               isp->smk_task = skp;
+               skp = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp);
+               if (skp == &smack_known_star || skp == &smack_known_web)
+                       skp = NULL;
+               isp->smk_mmap = skp;
 
                dput(dp);
                break;