smack: fix key permission verification
[platform/adaptation/renesas_rcar/renesas_kernel.git] / security / smack / smack_lsm.c
index 14f52be..c972a71 100644 (file)
@@ -880,18 +880,20 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
                return;
        }
 
-       skp = smk_import_entry(value, size);
        if (strcmp(name, XATTR_NAME_SMACK) == 0) {
+               skp = smk_import_entry(value, size);
                if (skp != NULL)
                        isp->smk_inode = skp->smk_known;
                else
                        isp->smk_inode = smack_known_invalid.smk_known;
        } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
+               skp = smk_import_entry(value, size);
                if (skp != NULL)
                        isp->smk_task = skp;
                else
                        isp->smk_task = &smack_known_invalid;
        } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
+               skp = smk_import_entry(value, size);
                if (skp != NULL)
                        isp->smk_mmap = skp;
                else
@@ -2713,6 +2715,15 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
         * of the superblock.
         */
        if (opt_dentry->d_parent == opt_dentry) {
+               if (sbp->s_magic == CGROUP_SUPER_MAGIC) {
+                       /*
+                        * The cgroup filesystem is never mounted,
+                        * so there's no opportunity to set the mount
+                        * options.
+                        */
+                       sbsp->smk_root = smack_known_star.smk_known;
+                       sbsp->smk_default = smack_known_star.smk_known;
+               }
                isp->smk_inode = sbsp->smk_root;
                isp->smk_flags |= SMK_INODE_INSTANT;
                goto unlockandout;
@@ -2726,16 +2737,20 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
         */
        switch (sbp->s_magic) {
        case SMACK_MAGIC:
+       case PIPEFS_MAGIC:
+       case SOCKFS_MAGIC:
+       case CGROUP_SUPER_MAGIC:
                /*
                 * Casey says that it's a little embarrassing
                 * that the smack file system doesn't do
                 * extended attributes.
-                */
-               final = smack_known_star.smk_known;
-               break;
-       case PIPEFS_MAGIC:
-               /*
+                *
                 * Casey says pipes are easy (?)
+                *
+                * Socket access is controlled by the socket
+                * structures associated with the task involved.
+                *
+                * Cgroupfs is special
                 */
                final = smack_known_star.smk_known;
                break;
@@ -2747,13 +2762,6 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
                 */
                final = ckp->smk_known;
                break;
-       case SOCKFS_MAGIC:
-               /*
-                * Socket access is controlled by the socket
-                * structures associated with the task involved.
-                */
-               final = smack_known_star.smk_known;
-               break;
        case PROC_SUPER_MAGIC:
                /*
                 * Casey says procfs appears not to care.
@@ -3506,11 +3514,12 @@ static void smack_key_free(struct key *key)
  * an error code otherwise
  */
 static int smack_key_permission(key_ref_t key_ref,
-                               const struct cred *cred, key_perm_t perm)
+                               const struct cred *cred, unsigned perm)
 {
        struct key *keyp;
        struct smk_audit_info ad;
        struct smack_known *tkp = smk_of_task(cred->security);
+       int request = 0;
 
        keyp = key_ref_to_ptr(key_ref);
        if (keyp == NULL)
@@ -3531,7 +3540,11 @@ static int smack_key_permission(key_ref_t key_ref,
        ad.a.u.key_struct.key = keyp->serial;
        ad.a.u.key_struct.key_desc = keyp->description;
 #endif
-       return smk_access(tkp, keyp->security, MAY_READWRITE, &ad);
+       if (perm & KEY_NEED_READ)
+               request = MAY_READ;
+       if (perm & (KEY_NEED_WRITE | KEY_NEED_LINK | KEY_NEED_SETATTR))
+               request = MAY_WRITE;
+       return smk_access(tkp, keyp->security, request, &ad);
 }
 #endif /* CONFIG_KEYS */