Smack: Prevent the * and @ labels from being used in SMACK64EXEC
[platform/adaptation/renesas_rcar/renesas_kernel.git] / security / smack / smack_lsm.c
index b0be893..62ebf4f 100644 (file)
@@ -837,31 +837,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);
 
@@ -2847,8 +2859,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;