summaryrefslogtreecommitdiff
path: root/security/apparmor
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2017-06-04 12:22:22 -0700
committerJohn Johansen <john.johansen@canonical.com>2017-06-10 17:11:32 -0700
commit60285eb3e7c8827e00e2f2b54561a8cca07d802f (patch)
tree3f4ea89339e63e1a522e0d6d814f64348e555e5e /security/apparmor
parent3664268f19ea07bec55df92fe53ff9ed28968bcc (diff)
apparmor: fix policy load/remove semantics
The namespace being passed into the replace/remove profiles fns() is not the view, but the namespace specified by the inode from the file hook (if present) or the loading tasks ns, if accessing the top level virtualized load/replace file interface. Signed-off-by: John Johansen <john.johansen@canonical.com>
Diffstat (limited to 'security/apparmor')
-rw-r--r--security/apparmor/apparmorfs.c6
-rw-r--r--security/apparmor/policy.c22
2 files changed, 13 insertions, 15 deletions
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 105a1da57b8f..4f4cd98d2b3b 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -418,8 +418,7 @@ static ssize_t policy_update(u32 mask, const char __user *buf, size_t size,
data = aa_simple_write_to_buffer(buf, size, size, pos);
error = PTR_ERR(data);
if (!IS_ERR(data)) {
- error = aa_replace_profiles(ns ? ns : profile->ns, profile,
- mask, data);
+ error = aa_replace_profiles(ns, profile, mask, data);
aa_put_loaddata(data);
}
@@ -486,8 +485,7 @@ static ssize_t profile_remove(struct file *f, const char __user *buf,
error = PTR_ERR(data);
if (!IS_ERR(data)) {
data->data[size] = 0;
- error = aa_remove_profiles(ns ? ns : profile->ns, profile,
- data->data, size);
+ error = aa_remove_profiles(ns, profile, data->data, size);
aa_put_loaddata(data);
}
out:
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index d95aae6bf710..29e04638790f 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -831,7 +831,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
+ * @policy_ns: namespace load is occurring on
* @label: label that is attempting to load/replace policy
* @mask: permission mask
* @udata: serialized data stream (NOT NULL)
@@ -842,7 +842,7 @@ 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,
+ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
u32 mask, struct aa_loaddata *udata)
{
const char *ns_name, *info = NULL;
@@ -885,7 +885,8 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
count++;
}
if (ns_name) {
- ns = aa_prepare_ns(view, ns_name);
+ ns = aa_prepare_ns(policy_ns ? policy_ns : profile->ns,
+ ns_name);
if (IS_ERR(ns)) {
op = OP_PROF_LOAD;
info = "failed to prepare namespace";
@@ -895,7 +896,7 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
goto fail;
}
} else
- ns = aa_get_ns(view);
+ ns = aa_get_ns(policy_ns ? policy_ns : profile->ns);
mutex_lock(&ns->lock);
/* check for duplicate rawdata blobs: space and file dedup */
@@ -1090,7 +1091,7 @@ fail:
/**
* aa_remove_profiles - remove profile(s) from the system
- * @view: namespace the remove is being done from
+ * @policy_ns: namespace the remove is being done from
* @subj: profile attempting to remove policy
* @fqname: name of the profile or namespace to remove (NOT NULL)
* @size: size of the name
@@ -1102,10 +1103,10 @@ fail:
*
* Returns: size of data consume else error code if fails
*/
-ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
+ssize_t aa_remove_profiles(struct aa_ns *policy_ns, struct aa_profile *subj,
char *fqname, size_t size)
{
- struct aa_ns *root = NULL, *ns = NULL;
+ struct aa_ns *ns = NULL;
struct aa_profile *profile = NULL;
const char *name = fqname, *info = NULL;
const char *ns_name = NULL;
@@ -1117,14 +1118,13 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
goto fail;
}
- root = view;
-
if (fqname[0] == ':') {
size_t ns_len;
name = aa_splitn_fqname(fqname, size, &ns_name, &ns_len);
/* released below */
- ns = aa_lookupn_ns(root, ns_name, ns_len);
+ ns = aa_lookupn_ns(policy_ns ? policy_ns : subj->ns, ns_name,
+ ns_len);
if (!ns) {
info = "namespace does not exist";
error = -ENOENT;
@@ -1132,7 +1132,7 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
}
} else
/* released below */
- ns = aa_get_ns(root);
+ ns = aa_get_ns(policy_ns ? policy_ns : subj->ns);
if (!name) {
/* remove namespace - can only happen if fqname[0] == ':' */