Commit 60285eb3 authored by John Johansen's avatar John Johansen

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: default avatarJohn Johansen <john.johansen@canonical.com>
parent 3664268f
...@@ -418,8 +418,7 @@ static ssize_t policy_update(u32 mask, const char __user *buf, size_t size, ...@@ -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); data = aa_simple_write_to_buffer(buf, size, size, pos);
error = PTR_ERR(data); error = PTR_ERR(data);
if (!IS_ERR(data)) { if (!IS_ERR(data)) {
error = aa_replace_profiles(ns ? ns : profile->ns, profile, error = aa_replace_profiles(ns, profile, mask, data);
mask, data);
aa_put_loaddata(data); aa_put_loaddata(data);
} }
...@@ -486,8 +485,7 @@ static ssize_t profile_remove(struct file *f, const char __user *buf, ...@@ -486,8 +485,7 @@ static ssize_t profile_remove(struct file *f, const char __user *buf,
error = PTR_ERR(data); error = PTR_ERR(data);
if (!IS_ERR(data)) { if (!IS_ERR(data)) {
data->data[size] = 0; data->data[size] = 0;
error = aa_remove_profiles(ns ? ns : profile->ns, profile, error = aa_remove_profiles(ns, profile, data->data, size);
data->data, size);
aa_put_loaddata(data); aa_put_loaddata(data);
} }
out: out:
......
...@@ -831,7 +831,7 @@ static int __lookup_replace(struct aa_ns *ns, const char *hname, ...@@ -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 * 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 * @label: label that is attempting to load/replace policy
* @mask: permission mask * @mask: permission mask
* @udata: serialized data stream (NOT NULL) * @udata: serialized data stream (NOT NULL)
...@@ -842,7 +842,7 @@ static int __lookup_replace(struct aa_ns *ns, const char *hname, ...@@ -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. * 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) u32 mask, struct aa_loaddata *udata)
{ {
const char *ns_name, *info = NULL; const char *ns_name, *info = NULL;
...@@ -885,7 +885,8 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile, ...@@ -885,7 +885,8 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
count++; count++;
} }
if (ns_name) { 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)) { if (IS_ERR(ns)) {
op = OP_PROF_LOAD; op = OP_PROF_LOAD;
info = "failed to prepare namespace"; info = "failed to prepare namespace";
...@@ -895,7 +896,7 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile, ...@@ -895,7 +896,7 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
goto fail; goto fail;
} }
} else } else
ns = aa_get_ns(view); ns = aa_get_ns(policy_ns ? policy_ns : profile->ns);
mutex_lock(&ns->lock); mutex_lock(&ns->lock);
/* check for duplicate rawdata blobs: space and file dedup */ /* check for duplicate rawdata blobs: space and file dedup */
...@@ -1090,7 +1091,7 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile, ...@@ -1090,7 +1091,7 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
/** /**
* aa_remove_profiles - remove profile(s) from the system * 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 * @subj: profile attempting to remove policy
* @fqname: name of the profile or namespace to remove (NOT NULL) * @fqname: name of the profile or namespace to remove (NOT NULL)
* @size: size of the name * @size: size of the name
...@@ -1102,10 +1103,10 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile, ...@@ -1102,10 +1103,10 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
* *
* Returns: size of data consume else error code if fails * 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) char *fqname, size_t size)
{ {
struct aa_ns *root = NULL, *ns = NULL; struct aa_ns *ns = NULL;
struct aa_profile *profile = NULL; struct aa_profile *profile = NULL;
const char *name = fqname, *info = NULL; const char *name = fqname, *info = NULL;
const char *ns_name = NULL; const char *ns_name = NULL;
...@@ -1117,14 +1118,13 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj, ...@@ -1117,14 +1118,13 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
goto fail; goto fail;
} }
root = view;
if (fqname[0] == ':') { if (fqname[0] == ':') {
size_t ns_len; size_t ns_len;
name = aa_splitn_fqname(fqname, size, &ns_name, &ns_len); name = aa_splitn_fqname(fqname, size, &ns_name, &ns_len);
/* released below */ /* 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) { if (!ns) {
info = "namespace does not exist"; info = "namespace does not exist";
error = -ENOENT; error = -ENOENT;
...@@ -1132,7 +1132,7 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj, ...@@ -1132,7 +1132,7 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
} }
} else } else
/* released below */ /* released below */
ns = aa_get_ns(root); ns = aa_get_ns(policy_ns ? policy_ns : subj->ns);
if (!name) { if (!name) {
/* remove namespace - can only happen if fqname[0] == ':' */ /* remove namespace - can only happen if fqname[0] == ':' */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment