aboutsummaryrefslogtreecommitdiff
path: root/security/smack/smack_access.c
diff options
context:
space:
mode:
authorRafal Krypa <r.krypa@samsung.com>2015-06-02 11:23:48 +0200
committerCasey Schaufler <casey@schaufler-ca.com>2015-06-02 11:53:42 -0700
commitc0d77c884461fc0dec0411e49797dc3f3651c31b (patch)
treec526c2ae841b0fc358d29af69cddcdb63ae72431 /security/smack/smack_access.c
parent01fa8474fba7e80f6a2ac31d0790385a993cb7ba (diff)
downloadlinux-c0d77c884461fc0dec0411e49797dc3f3651c31b.tar.gz
Smack: allow multiple labels in onlycap
Smack onlycap allows limiting of CAP_MAC_ADMIN and CAP_MAC_OVERRIDE to processes running with the configured label. But having single privileged label is not enough in some real use cases. On a complex system like Tizen, there maybe few programs that need to configure Smack policy in run-time and running them all with a single label is not always practical. This patch extends onlycap feature for multiple labels. They are configured in the same smackfs "onlycap" interface, separated by spaces. Signed-off-by: Rafal Krypa <r.krypa@samsung.com>
Diffstat (limited to 'security/smack/smack_access.c')
-rw-r--r--security/smack/smack_access.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 408e20be1ad7..00f6b38bffbd 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -617,3 +617,44 @@ struct smack_known *smack_from_secid(const u32 secid)
rcu_read_unlock();
return &smack_known_invalid;
}
+
+/*
+ * Unless a process is running with one of these labels
+ * even having CAP_MAC_OVERRIDE isn't enough to grant
+ * privilege to violate MAC policy. If no labels are
+ * designated (the empty list case) capabilities apply to
+ * everyone.
+ */
+LIST_HEAD(smack_onlycap_list);
+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.
+ */
+int smack_privileged(int cap)
+{
+ struct smack_known *skp = smk_of_current();
+ struct smack_onlycap *sop;
+
+ if (!capable(cap))
+ return 0;
+
+ rcu_read_lock();
+ if (list_empty(&smack_onlycap_list)) {
+ rcu_read_unlock();
+ return 1;
+ }
+
+ list_for_each_entry_rcu(sop, &smack_onlycap_list, list) {
+ if (sop->smk_label == skp) {
+ rcu_read_unlock();
+ return 1;
+ }
+ }
+ rcu_read_unlock();
+
+ return 0;
+}