smack: fix: allow either entry be missing on access/access2 check (v2) 31/19431/1
authorCasey Schaufler <casey@schaufler-ca.com>
Tue, 28 Jan 2014 19:31:46 +0000 (11:31 -0800)
committerStanislav Vorobiov <s.vorobiov@samsung.com>
Fri, 11 Apr 2014 14:10:49 +0000 (18:10 +0400)
commit 398ce073700a2a3e86b5a0b1edecdddfa3996b27
Author: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Date:   Thu Nov 28 19:16:46 2013 +0200

    smack: fix: allow either entry be missing on access/access2 check (v2)

    This is a regression caused by f7112e6c. When either subject or
    object is not found the answer for access should be no. This
    patch fixes the situation. '0' is written back instead of failing
    with -EINVAL.

    v2: cosmetic style fixes

Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Change-Id: Ibb84d8ab1e70d5f6689705ed28b0946b9ddde21d
Signed-off-by: Casey Schaufler <casey.schaufler@intel.com>
security/smack/smackfs.c

index bd5c6e197504ffc38ba8c3810c1d33b7211748c3..f5a6bb8e282848e8ec1247c7d46e881b92b5a814 100644 (file)
@@ -309,7 +309,8 @@ static int smk_perm_from_str(const char *string)
  * @import: if non-zero, import labels
  * @len: label length limit
  *
- * Returns 0 on success, -1 on failure
+ * Returns 0 on success, -EINVAL on failure and -ENOENT when either subject
+ * or object is missing.
  */
 static int smk_fill_rule(const char *subject, const char *object,
                                const char *access1, const char *access2,
@@ -322,28 +323,28 @@ static int smk_fill_rule(const char *subject, const char *object,
        if (import) {
                rule->smk_subject = smk_import_entry(subject, len);
                if (rule->smk_subject == NULL)
-                       return -1;
+                       return -EINVAL;
 
                rule->smk_object = smk_import(object, len);
                if (rule->smk_object == NULL)
-                       return -1;
+                       return -EINVAL;
        } else {
                cp = smk_parse_smack(subject, len);
                if (cp == NULL)
-                       return -1;
+                       return -EINVAL;
                skp = smk_find_entry(cp);
                kfree(cp);
                if (skp == NULL)
-                       return -1;
+                       return -ENOENT;
                rule->smk_subject = skp;
 
                cp = smk_parse_smack(object, len);
                if (cp == NULL)
-                       return -1;
+                       return -EINVAL;
                skp = smk_find_entry(cp);
                kfree(cp);
                if (skp == NULL)
-                       return -1;
+                       return -ENOENT;
                rule->smk_object = skp->smk_known;
        }
 
@@ -389,6 +390,7 @@ static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule,
 {
        ssize_t cnt = 0;
        char *tok[4];
+       int rc;
        int i;
 
        /*
@@ -413,10 +415,8 @@ static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule,
        while (i < 4)
                tok[i++] = NULL;
 
-       if (smk_fill_rule(tok[0], tok[1], tok[2], tok[3], rule, import, 0))
-               return -1;
-
-       return cnt;
+       rc = smk_fill_rule(tok[0], tok[1], tok[2], tok[3], rule, import, 0);
+       return rc == 0 ? cnt : rc;
 }
 
 #define SMK_FIXED24_FMT        0       /* Fixed 24byte label format */
@@ -1864,11 +1864,12 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf,
                res = smk_parse_long_rule(data, &rule, 0, 3);
        }
 
-       if (res < 0)
+       if (res >= 0)
+               res = smk_access(rule.smk_subject, rule.smk_object,
+                                rule.smk_access1, NULL);
+       else if (res != -ENOENT)
                return -EINVAL;
 
-       res = smk_access(rule.smk_subject, rule.smk_object,
-                               rule.smk_access1, NULL);
        data[0] = res == 0 ? '1' : '0';
        data[1] = '\0';