Smack: Correctly remove SMACK64TRANSMUTE attribute
[platform/adaptation/renesas_rcar/renesas_kernel.git] / security / smack / smack_lsm.c
index 23d90cd..1c05130 100644 (file)
@@ -178,7 +178,8 @@ static inline unsigned int smk_ptrace_mode(unsigned int mode)
 /**
  * smk_ptrace_rule_check - helper for ptrace access
  * @tracer: tracer process
- * @tracee_label: label of the process that's about to be traced
+ * @tracee_label: label of the process that's about to be traced,
+ *                the pointer must originate from smack structures
  * @mode: ptrace attachment mode (PTRACE_MODE_*)
  * @func: name of the function that called us, used for audit
  *
@@ -201,6 +202,25 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, char *tracee_label,
        tsp = task_security(tracer);
        skp = smk_of_task(tsp);
 
+       if ((mode & PTRACE_MODE_ATTACH) &&
+           (smack_ptrace_rule == SMACK_PTRACE_EXACT ||
+            smack_ptrace_rule == SMACK_PTRACE_DRACONIAN)) {
+               if (skp->smk_known == tracee_label)
+                       rc = 0;
+               else if (smack_ptrace_rule == SMACK_PTRACE_DRACONIAN)
+                       rc = -EACCES;
+               else if (capable(CAP_SYS_PTRACE))
+                       rc = 0;
+               else
+                       rc = -EACCES;
+
+               if (saip)
+                       smack_log(skp->smk_known, tracee_label, 0, rc, saip);
+
+               return rc;
+       }
+
+       /* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */
        rc = smk_tskacc(tsp, tracee_label, smk_ptrace_mode(mode), saip);
        return rc;
 }
@@ -1000,24 +1020,37 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
            strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
            strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
            strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 ||
-           strcmp(name, XATTR_NAME_SMACKMMAP)) {
+           strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
                if (!smack_privileged(CAP_MAC_ADMIN))
                        rc = -EPERM;
        } else
                rc = cap_inode_removexattr(dentry, name);
 
+       if (rc != 0)
+               return rc;
+
        smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
        smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
-       if (rc == 0)
-               rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
 
-       if (rc == 0) {
-               isp = dentry->d_inode->i_security;
+       rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
+       if (rc != 0)
+               return rc;
+
+       isp = dentry->d_inode->i_security;
+       /*
+        * Don't do anything special for these.
+        *      XATTR_NAME_SMACKIPIN
+        *      XATTR_NAME_SMACKIPOUT
+        *      XATTR_NAME_SMACKEXEC
+        */
+       if (strcmp(name, XATTR_NAME_SMACK) == 0)
                isp->smk_task = NULL;
+       else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0)
                isp->smk_mmap = NULL;
-       }
+       else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0)
+               isp->smk_flags &= ~SMK_INODE_TRANSMUTE;
 
-       return rc;
+       return 0;
 }
 
 /**
@@ -2138,7 +2171,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
        int rc = 0;
 
        if (value == NULL || size > SMK_LONGLABEL || size == 0)
-               return -EACCES;
+               return -EINVAL;
 
        skp = smk_import_entry(value, size);
        if (skp == NULL)