diff options
author | Rafal Krypa <r.krypa@samsung.com> | 2015-06-02 11:23:48 +0200 |
---|---|---|
committer | Casey Schaufler <casey@schaufler-ca.com> | 2015-06-02 20:53:42 +0200 |
commit | c0d77c884461fc0dec0411e49797dc3f3651c31b (patch) | |
tree | c526c2ae841b0fc358d29af69cddcdb63ae72431 /security/smack/smack_access.c | |
parent | Smack: fix seq operations in smackfs (diff) | |
download | linux-c0d77c884461fc0dec0411e49797dc3f3651c31b.tar.xz linux-c0d77c884461fc0dec0411e49797dc3f3651c31b.zip |
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.c | 41 |
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; +} |