Loading security/apparmor/apparmorfs.c +7 −8 Original line number Diff line number Diff line Loading @@ -400,17 +400,16 @@ static struct aa_loaddata *aa_simple_write_to_buffer(const char __user *userbuf, return data; } static ssize_t policy_update(int binop, const char __user *buf, size_t size, static ssize_t policy_update(u32 mask, const char __user *buf, size_t size, loff_t *pos, struct aa_ns *ns) { ssize_t error; struct aa_loaddata *data; struct aa_profile *profile = aa_current_profile(); const char *op = binop == PROF_ADD ? OP_PROF_LOAD : OP_PROF_REPL; /* high level check about policy management - fine grained in * below after unpack */ error = aa_may_manage_policy(profile, ns, op); error = aa_may_manage_policy(profile, ns, mask); if (error) return error; Loading @@ -418,7 +417,7 @@ static ssize_t policy_update(int binop, const char __user *buf, size_t size, error = PTR_ERR(data); if (!IS_ERR(data)) { error = aa_replace_profiles(ns ? ns : profile->ns, profile, binop, data); mask, data); aa_put_loaddata(data); } Loading @@ -430,7 +429,7 @@ static ssize_t profile_load(struct file *f, const char __user *buf, size_t size, loff_t *pos) { struct aa_ns *ns = aa_get_ns(f->f_inode->i_private); int error = policy_update(PROF_ADD, buf, size, pos, ns); int error = policy_update(AA_MAY_LOAD_POLICY, buf, size, pos, ns); aa_put_ns(ns); Loading @@ -447,8 +446,8 @@ static ssize_t profile_replace(struct file *f, const char __user *buf, size_t size, loff_t *pos) { struct aa_ns *ns = aa_get_ns(f->f_inode->i_private); int error = policy_update(PROF_REPLACE, buf, size, pos, ns); int error = policy_update(AA_MAY_LOAD_POLICY | AA_MAY_REPLACE_POLICY, buf, size, pos, ns); aa_put_ns(ns); return error; Loading @@ -472,7 +471,7 @@ static ssize_t profile_remove(struct file *f, const char __user *buf, /* high level check about policy management - fine grained in * below after unpack */ error = aa_may_manage_policy(profile, ns, OP_PROF_RM); error = aa_may_manage_policy(profile, ns, AA_MAY_REMOVE_POLICY); if (error) goto out; Loading security/apparmor/include/policy.h +6 −2 Original line number Diff line number Diff line Loading @@ -188,6 +188,10 @@ struct aa_profile { extern enum profile_mode aa_g_profile_mode; #define AA_MAY_LOAD_POLICY AA_MAY_APPEND #define AA_MAY_REPLACE_POLICY AA_MAY_WRITE #define AA_MAY_REMOVE_POLICY AA_MAY_DELETE void __aa_update_proxy(struct aa_profile *orig, struct aa_profile *new); void aa_add_profile(struct aa_policy *common, struct aa_profile *profile); Loading @@ -208,7 +212,7 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_profile *base, struct aa_profile *aa_match_profile(struct aa_ns *ns, const char *name); 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); ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *profile, char *name, size_t size); void __aa_profile_list_release(struct list_head *head); Loading Loading @@ -323,6 +327,6 @@ static inline int AUDIT_MODE(struct aa_profile *profile) bool policy_view_capable(struct aa_ns *ns); bool policy_admin_capable(struct aa_ns *ns); int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns, const char *op); u32 mask); #endif /* __AA_POLICY_H */ security/apparmor/policy.c +22 −13 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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); Loading Loading @@ -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; } Loading Loading
security/apparmor/apparmorfs.c +7 −8 Original line number Diff line number Diff line Loading @@ -400,17 +400,16 @@ static struct aa_loaddata *aa_simple_write_to_buffer(const char __user *userbuf, return data; } static ssize_t policy_update(int binop, const char __user *buf, size_t size, static ssize_t policy_update(u32 mask, const char __user *buf, size_t size, loff_t *pos, struct aa_ns *ns) { ssize_t error; struct aa_loaddata *data; struct aa_profile *profile = aa_current_profile(); const char *op = binop == PROF_ADD ? OP_PROF_LOAD : OP_PROF_REPL; /* high level check about policy management - fine grained in * below after unpack */ error = aa_may_manage_policy(profile, ns, op); error = aa_may_manage_policy(profile, ns, mask); if (error) return error; Loading @@ -418,7 +417,7 @@ static ssize_t policy_update(int binop, const char __user *buf, size_t size, error = PTR_ERR(data); if (!IS_ERR(data)) { error = aa_replace_profiles(ns ? ns : profile->ns, profile, binop, data); mask, data); aa_put_loaddata(data); } Loading @@ -430,7 +429,7 @@ static ssize_t profile_load(struct file *f, const char __user *buf, size_t size, loff_t *pos) { struct aa_ns *ns = aa_get_ns(f->f_inode->i_private); int error = policy_update(PROF_ADD, buf, size, pos, ns); int error = policy_update(AA_MAY_LOAD_POLICY, buf, size, pos, ns); aa_put_ns(ns); Loading @@ -447,8 +446,8 @@ static ssize_t profile_replace(struct file *f, const char __user *buf, size_t size, loff_t *pos) { struct aa_ns *ns = aa_get_ns(f->f_inode->i_private); int error = policy_update(PROF_REPLACE, buf, size, pos, ns); int error = policy_update(AA_MAY_LOAD_POLICY | AA_MAY_REPLACE_POLICY, buf, size, pos, ns); aa_put_ns(ns); return error; Loading @@ -472,7 +471,7 @@ static ssize_t profile_remove(struct file *f, const char __user *buf, /* high level check about policy management - fine grained in * below after unpack */ error = aa_may_manage_policy(profile, ns, OP_PROF_RM); error = aa_may_manage_policy(profile, ns, AA_MAY_REMOVE_POLICY); if (error) goto out; Loading
security/apparmor/include/policy.h +6 −2 Original line number Diff line number Diff line Loading @@ -188,6 +188,10 @@ struct aa_profile { extern enum profile_mode aa_g_profile_mode; #define AA_MAY_LOAD_POLICY AA_MAY_APPEND #define AA_MAY_REPLACE_POLICY AA_MAY_WRITE #define AA_MAY_REMOVE_POLICY AA_MAY_DELETE void __aa_update_proxy(struct aa_profile *orig, struct aa_profile *new); void aa_add_profile(struct aa_policy *common, struct aa_profile *profile); Loading @@ -208,7 +212,7 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_profile *base, struct aa_profile *aa_match_profile(struct aa_ns *ns, const char *name); 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); ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *profile, char *name, size_t size); void __aa_profile_list_release(struct list_head *head); Loading Loading @@ -323,6 +327,6 @@ static inline int AUDIT_MODE(struct aa_profile *profile) bool policy_view_capable(struct aa_ns *ns); bool policy_admin_capable(struct aa_ns *ns); int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns, const char *op); u32 mask); #endif /* __AA_POLICY_H */
security/apparmor/policy.c +22 −13 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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); Loading Loading @@ -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; } Loading