summaryrefslogtreecommitdiff
path: root/security/apparmor/policy.c
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2017-05-26 11:45:08 +0300
committerJohn Johansen <john.johansen@canonical.com>2017-06-11 03:11:20 +0300
commit18e99f191a8e66ec8fd06e4820de44bd9faa296a (patch)
tree66b652100c9458c616a1afd0d208ad337a5058dc /security/apparmor/policy.c
parente53cfe6c7caa79ccdccce53e600dae522acb1c84 (diff)
downloadlinux-18e99f191a8e66ec8fd06e4820de44bd9faa296a.tar.xz
apparmor: provide finer control over policy management
Signed-off-by: John Johansen <john.johansen@canonical.com>
Diffstat (limited to 'security/apparmor/policy.c')
-rw-r--r--security/apparmor/policy.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index a5e8559e4dec..65e98d0491f4 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -690,17 +690,25 @@ bool policy_admin_capable(struct aa_ns *ns)
*
* Returns: 0 if the task is allowed to manipulate policy else error
*/
-int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns,
- const char *op)
+int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns, u32 mask)
{
+ const char *op;
+
+ if (mask & AA_MAY_REMOVE_POLICY)
+ op = OP_PROF_RM;
+ else if (mask & AA_MAY_REPLACE_POLICY)
+ op = OP_PROF_REPL;
+ else
+ op = OP_PROF_LOAD;
+
/* check if loading policy is locked out */
if (aa_g_lock_policy)
- return audit_policy(profile, op, NULL, NULL,
- "policy_locked", -EACCES);
+ return audit_policy(profile, op, NULL, NULL, "policy_locked",
+ -EACCES);
if (!policy_admin_capable(ns))
- return audit_policy(profile, op, NULL, NULL,
- "not policy admin", -EACCES);
+ return audit_policy(profile, op, NULL, NULL, "not policy admin",
+ -EACCES);
/* TODO: add fine grained mediation of policy loads */
return 0;
@@ -825,7 +833,7 @@ static int __lookup_replace(struct aa_ns *ns, const char *hname,
* aa_replace_profiles - replace profile(s) on the profile list
* @view: namespace load is viewed from
* @label: label that is attempting to load/replace policy
- * @noreplace: true if only doing addition, no replacement allowed
+ * @mask: permission mask
* @udata: serialized data stream (NOT NULL)
*
* unpack and replace a profile on the profile list and uses of that profile
@@ -835,17 +843,17 @@ static int __lookup_replace(struct aa_ns *ns, const char *hname,
* Returns: size of data consumed else error code on failure.
*/
ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
- bool noreplace, struct aa_loaddata *udata)
+ u32 mask, struct aa_loaddata *udata)
{
const char *ns_name, *info = NULL;
struct aa_ns *ns = NULL;
struct aa_load_ent *ent, *tmp;
struct aa_loaddata *rawdata_ent;
- const char *op = OP_PROF_REPL;
+ const char *op;
ssize_t count, error;
-
LIST_HEAD(lh);
+ op = mask & AA_MAY_REPLACE_POLICY ? OP_PROF_REPL : OP_PROF_LOAD;
aa_get_loaddata(udata);
/* released below */
error = aa_unpack(udata, &lh, &ns_name);
@@ -909,15 +917,16 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
struct aa_policy *policy;
ent->new->rawdata = aa_get_loaddata(udata);
- error = __lookup_replace(ns, ent->new->base.hname, noreplace,
+ error = __lookup_replace(ns, ent->new->base.hname,
+ !(mask & AA_MAY_REPLACE_POLICY),
&ent->old, &info);
if (error)
goto fail_lock;
if (ent->new->rename) {
error = __lookup_replace(ns, ent->new->rename,
- noreplace, &ent->rename,
- &info);
+ !(mask & AA_MAY_REPLACE_POLICY),
+ &ent->rename, &info);
if (error)
goto fail_lock;
}