Smack: Use cap_capable in privilege check
authorCasey Schaufler <casey@schaufler-ca.com>
Wed, 31 May 2017 20:23:41 +0000 (13:23 -0700)
committerCasey Schaufler <casey@schaufler-ca.com>
Thu, 1 Jun 2017 16:27:21 +0000 (09:27 -0700)
Use cap_capable() rather than capable() in the Smack privilege
check as the former does not invoke other security module
privilege check, while the later does. This becomes important
when stacking. It may be a problem even with minor modules.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
security/smack/smack.h
security/smack/smack_access.c

index 612b810fbbc6359838c2a54429a49e88106d9549..6a71fc7831ab58b0b8a85468eb783a7c895b7892 100644 (file)
@@ -320,7 +320,7 @@ int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int);
 struct smack_known *smk_import_entry(const char *, int);
 void smk_insert_entry(struct smack_known *skp);
 struct smack_known *smk_find_entry(const char *);
-int smack_privileged(int cap);
+bool smack_privileged(int cap);
 void smk_destroy_label_list(struct list_head *list);
 
 /*
index a4b2e6b94abd49f8dde1aa04c4f61f99b40a0ff5..1a3004189447e6130351b1e87cdc150cfd7e3436 100644 (file)
@@ -627,35 +627,38 @@ DEFINE_MUTEX(smack_onlycap_lock);
  * Is the task privileged and allowed to be privileged
  * by the onlycap rule.
  *
- * Returns 1 if the task is allowed to be privileged, 0 if it's not.
+ * Returns true if the task is allowed to be privileged, false if it's not.
  */
-int smack_privileged(int cap)
+bool smack_privileged(int cap)
 {
        struct smack_known *skp = smk_of_current();
        struct smack_known_list_elem *sklep;
+       int rc;
 
        /*
         * All kernel tasks are privileged
         */
        if (unlikely(current->flags & PF_KTHREAD))
-               return 1;
+               return true;
 
-       if (!capable(cap))
-               return 0;
+       rc = cap_capable(current_cred(), &init_user_ns, cap,
+                               SECURITY_CAP_AUDIT);
+       if (rc)
+               return false;
 
        rcu_read_lock();
        if (list_empty(&smack_onlycap_list)) {
                rcu_read_unlock();
-               return 1;
+               return true;
        }
 
        list_for_each_entry_rcu(sklep, &smack_onlycap_list, list) {
                if (sklep->smk_label == skp) {
                        rcu_read_unlock();
-                       return 1;
+                       return true;
                }
        }
        rcu_read_unlock();
 
-       return 0;
+       return false;
 }