/*1* AppArmor security module2*3* This file contains AppArmor policy manipulation functions4*5* Copyright (C) 1998-2008 Novell/SUSE6* Copyright 2009-2010 Canonical Ltd.7*8* This program is free software; you can redistribute it and/or9* modify it under the terms of the GNU General Public License as10* published by the Free Software Foundation, version 2 of the11* License.12*13*14* AppArmor policy is based around profiles, which contain the rules a15* task is confined by. Every task in the system has a profile attached16* to it determined either by matching "unconfined" tasks against the17* visible set of profiles or by following a profiles attachment rules.18*19* Each profile exists in a profile namespace which is a container of20* visible profiles. Each namespace contains a special "unconfined" profile,21* which doesn't enforce any confinement on a task beyond DAC.22*23* Namespace and profile names can be written together in either24* of two syntaxes.25* :namespace:profile - used by kernel interfaces for easy detection26* namespace://profile - used by policy27*28* Profile names can not start with : or @ or ^ and may not contain \029*30* Reserved profile names31* unconfined - special automatically generated unconfined profile32* inherit - special name to indicate profile inheritance33* null-XXXX-YYYY - special automatically generated learning profiles34*35* Namespace names may not start with / or @ and may not contain \0 or :36* Reserved namespace names37* user-XXXX - user defined profiles38*39* a // in a profile or namespace name indicates a hierarchical name with the40* name before the // being the parent and the name after the child.41*42* Profile and namespace hierarchies serve two different but similar purposes.43* The namespace contains the set of visible profiles that are considered44* for attachment. The hierarchy of namespaces allows for virtualizing45* the namespace so that for example a chroot can have its own set of profiles46* which may define some local user namespaces.47* The profile hierarchy severs two distinct purposes,48* - it allows for sub profiles or hats, which allows an application to run49* subprograms under its own profile with different restriction than it50* self, and not have it use the system profile.51* eg. if a mail program starts an editor, the policy might make the52* restrictions tighter on the editor tighter than the mail program,53* and definitely different than general editor restrictions54* - it allows for binary hierarchy of profiles, so that execution history55* is preserved. This feature isn't exploited by AppArmor reference policy56* but is allowed. NOTE: this is currently suboptimal because profile57* aliasing is not currently implemented so that a profile for each58* level must be defined.59* eg. /bin/bash///bin/ls as a name would indicate /bin/ls was started60* from /bin/bash61*62* A profile or namespace name that can contain one or more // separators63* is referred to as an hname (hierarchical).64* eg. /bin/bash//bin/ls65*66* An fqname is a name that may contain both namespace and profile hnames.67* eg. :ns:/bin/bash//bin/ls68*69* NOTES:70* - locking of profile lists is currently fairly coarse. All profile71* lists within a namespace use the namespace lock.72* FIXME: move profile lists to using rcu_lists73*/7475#include <linux/slab.h>76#include <linux/spinlock.h>77#include <linux/string.h>7879#include "include/apparmor.h"80#include "include/capability.h"81#include "include/context.h"82#include "include/file.h"83#include "include/ipc.h"84#include "include/match.h"85#include "include/path.h"86#include "include/policy.h"87#include "include/policy_unpack.h"88#include "include/resource.h"89#include "include/sid.h"909192/* root profile namespace */93struct aa_namespace *root_ns;9495const char *profile_mode_names[] = {96"enforce",97"complain",98"kill",99};100101/**102* hname_tail - find the last component of an hname103* @name: hname to find the base profile name component of (NOT NULL)104*105* Returns: the tail (base profile name) name component of an hname106*/107static const char *hname_tail(const char *hname)108{109char *split;110hname = strim((char *)hname);111for (split = strstr(hname, "//"); split; split = strstr(hname, "//"))112hname = split + 2;113114return hname;115}116117/**118* policy_init - initialize a policy structure119* @policy: policy to initialize (NOT NULL)120* @prefix: prefix name if any is required. (MAYBE NULL)121* @name: name of the policy, init will make a copy of it (NOT NULL)122*123* Note: this fn creates a copy of strings passed in124*125* Returns: true if policy init successful126*/127static bool policy_init(struct aa_policy *policy, const char *prefix,128const char *name)129{130/* freed by policy_free */131if (prefix) {132policy->hname = kmalloc(strlen(prefix) + strlen(name) + 3,133GFP_KERNEL);134if (policy->hname)135sprintf(policy->hname, "%s//%s", prefix, name);136} else137policy->hname = kstrdup(name, GFP_KERNEL);138if (!policy->hname)139return 0;140/* base.name is a substring of fqname */141policy->name = (char *)hname_tail(policy->hname);142INIT_LIST_HEAD(&policy->list);143INIT_LIST_HEAD(&policy->profiles);144kref_init(&policy->count);145146return 1;147}148149/**150* policy_destroy - free the elements referenced by @policy151* @policy: policy that is to have its elements freed (NOT NULL)152*/153static void policy_destroy(struct aa_policy *policy)154{155/* still contains profiles -- invalid */156if (!list_empty(&policy->profiles)) {157AA_ERROR("%s: internal error, "158"policy '%s' still contains profiles\n",159__func__, policy->name);160BUG();161}162if (!list_empty(&policy->list)) {163AA_ERROR("%s: internal error, policy '%s' still on list\n",164__func__, policy->name);165BUG();166}167168/* don't free name as its a subset of hname */169kzfree(policy->hname);170}171172/**173* __policy_find - find a policy by @name on a policy list174* @head: list to search (NOT NULL)175* @name: name to search for (NOT NULL)176*177* Requires: correct locks for the @head list be held178*179* Returns: unrefcounted policy that match @name or NULL if not found180*/181static struct aa_policy *__policy_find(struct list_head *head, const char *name)182{183struct aa_policy *policy;184185list_for_each_entry(policy, head, list) {186if (!strcmp(policy->name, name))187return policy;188}189return NULL;190}191192/**193* __policy_strn_find - find a policy that's name matches @len chars of @str194* @head: list to search (NOT NULL)195* @str: string to search for (NOT NULL)196* @len: length of match required197*198* Requires: correct locks for the @head list be held199*200* Returns: unrefcounted policy that match @str or NULL if not found201*202* if @len == strlen(@strlen) then this is equiv to __policy_find203* other wise it allows searching for policy by a partial match of name204*/205static struct aa_policy *__policy_strn_find(struct list_head *head,206const char *str, int len)207{208struct aa_policy *policy;209210list_for_each_entry(policy, head, list) {211if (aa_strneq(policy->name, str, len))212return policy;213}214215return NULL;216}217218/*219* Routines for AppArmor namespaces220*/221222static const char *hidden_ns_name = "---";223/**224* aa_ns_visible - test if @view is visible from @curr225* @curr: namespace to treat as the parent (NOT NULL)226* @view: namespace to test if visible from @curr (NOT NULL)227*228* Returns: true if @view is visible from @curr else false229*/230bool aa_ns_visible(struct aa_namespace *curr, struct aa_namespace *view)231{232if (curr == view)233return true;234235for ( ; view; view = view->parent) {236if (view->parent == curr)237return true;238}239return false;240}241242/**243* aa_na_name - Find the ns name to display for @view from @curr244* @curr - current namespace (NOT NULL)245* @view - namespace attempting to view (NOT NULL)246*247* Returns: name of @view visible from @curr248*/249const char *aa_ns_name(struct aa_namespace *curr, struct aa_namespace *view)250{251/* if view == curr then the namespace name isn't displayed */252if (curr == view)253return "";254255if (aa_ns_visible(curr, view)) {256/* at this point if a ns is visible it is in a view ns257* thus the curr ns.hname is a prefix of its name.258* Only output the virtualized portion of the name259* Add + 2 to skip over // separating curr hname prefix260* from the visible tail of the views hname261*/262return view->base.hname + strlen(curr->base.hname) + 2;263} else264return hidden_ns_name;265}266267/**268* alloc_namespace - allocate, initialize and return a new namespace269* @prefix: parent namespace name (MAYBE NULL)270* @name: a preallocated name (NOT NULL)271*272* Returns: refcounted namespace or NULL on failure.273*/274static struct aa_namespace *alloc_namespace(const char *prefix,275const char *name)276{277struct aa_namespace *ns;278279ns = kzalloc(sizeof(*ns), GFP_KERNEL);280AA_DEBUG("%s(%p)\n", __func__, ns);281if (!ns)282return NULL;283if (!policy_init(&ns->base, prefix, name))284goto fail_ns;285286INIT_LIST_HEAD(&ns->sub_ns);287rwlock_init(&ns->lock);288289/* released by free_namespace */290ns->unconfined = aa_alloc_profile("unconfined");291if (!ns->unconfined)292goto fail_unconfined;293294ns->unconfined->sid = aa_alloc_sid();295ns->unconfined->flags = PFLAG_UNCONFINED | PFLAG_IX_ON_NAME_ERROR |296PFLAG_IMMUTABLE;297298/*299* released by free_namespace, however __remove_namespace breaks300* the cyclic references (ns->unconfined, and unconfined->ns) and301* replaces with refs to parent namespace unconfined302*/303ns->unconfined->ns = aa_get_namespace(ns);304305return ns;306307fail_unconfined:308kzfree(ns->base.hname);309fail_ns:310kzfree(ns);311return NULL;312}313314/**315* free_namespace - free a profile namespace316* @ns: the namespace to free (MAYBE NULL)317*318* Requires: All references to the namespace must have been put, if the319* namespace was referenced by a profile confining a task,320*/321static void free_namespace(struct aa_namespace *ns)322{323if (!ns)324return;325326policy_destroy(&ns->base);327aa_put_namespace(ns->parent);328329if (ns->unconfined && ns->unconfined->ns == ns)330ns->unconfined->ns = NULL;331332aa_put_profile(ns->unconfined);333kzfree(ns);334}335336/**337* aa_free_namespace_kref - free aa_namespace by kref (see aa_put_namespace)338* @kr: kref callback for freeing of a namespace (NOT NULL)339*/340void aa_free_namespace_kref(struct kref *kref)341{342free_namespace(container_of(kref, struct aa_namespace, base.count));343}344345/**346* __aa_find_namespace - find a namespace on a list by @name347* @head: list to search for namespace on (NOT NULL)348* @name: name of namespace to look for (NOT NULL)349*350* Returns: unrefcounted namespace351*352* Requires: ns lock be held353*/354static struct aa_namespace *__aa_find_namespace(struct list_head *head,355const char *name)356{357return (struct aa_namespace *)__policy_find(head, name);358}359360/**361* aa_find_namespace - look up a profile namespace on the namespace list362* @root: namespace to search in (NOT NULL)363* @name: name of namespace to find (NOT NULL)364*365* Returns: a refcounted namespace on the list, or NULL if no namespace366* called @name exists.367*368* refcount released by caller369*/370struct aa_namespace *aa_find_namespace(struct aa_namespace *root,371const char *name)372{373struct aa_namespace *ns = NULL;374375read_lock(&root->lock);376ns = aa_get_namespace(__aa_find_namespace(&root->sub_ns, name));377read_unlock(&root->lock);378379return ns;380}381382/**383* aa_prepare_namespace - find an existing or create a new namespace of @name384* @name: the namespace to find or add (MAYBE NULL)385*386* Returns: refcounted namespace or NULL if failed to create one387*/388static struct aa_namespace *aa_prepare_namespace(const char *name)389{390struct aa_namespace *ns, *root;391392root = aa_current_profile()->ns;393394write_lock(&root->lock);395396/* if name isn't specified the profile is loaded to the current ns */397if (!name) {398/* released by caller */399ns = aa_get_namespace(root);400goto out;401}402403/* try and find the specified ns and if it doesn't exist create it */404/* released by caller */405ns = aa_get_namespace(__aa_find_namespace(&root->sub_ns, name));406if (!ns) {407/* namespace not found */408struct aa_namespace *new_ns;409write_unlock(&root->lock);410new_ns = alloc_namespace(root->base.hname, name);411if (!new_ns)412return NULL;413write_lock(&root->lock);414/* test for race when new_ns was allocated */415ns = __aa_find_namespace(&root->sub_ns, name);416if (!ns) {417/* add parent ref */418new_ns->parent = aa_get_namespace(root);419420list_add(&new_ns->base.list, &root->sub_ns);421/* add list ref */422ns = aa_get_namespace(new_ns);423} else {424/* raced so free the new one */425free_namespace(new_ns);426/* get reference on namespace */427aa_get_namespace(ns);428}429}430out:431write_unlock(&root->lock);432433/* return ref */434return ns;435}436437/**438* __list_add_profile - add a profile to a list439* @list: list to add it to (NOT NULL)440* @profile: the profile to add (NOT NULL)441*442* refcount @profile, should be put by __list_remove_profile443*444* Requires: namespace lock be held, or list not be shared445*/446static void __list_add_profile(struct list_head *list,447struct aa_profile *profile)448{449list_add(&profile->base.list, list);450/* get list reference */451aa_get_profile(profile);452}453454/**455* __list_remove_profile - remove a profile from the list it is on456* @profile: the profile to remove (NOT NULL)457*458* remove a profile from the list, warning generally removal should459* be done with __replace_profile as most profile removals are460* replacements to the unconfined profile.461*462* put @profile list refcount463*464* Requires: namespace lock be held, or list not have been live465*/466static void __list_remove_profile(struct aa_profile *profile)467{468list_del_init(&profile->base.list);469if (!(profile->flags & PFLAG_NO_LIST_REF))470/* release list reference */471aa_put_profile(profile);472}473474/**475* __replace_profile - replace @old with @new on a list476* @old: profile to be replaced (NOT NULL)477* @new: profile to replace @old with (NOT NULL)478*479* Will duplicate and refcount elements that @new inherits from @old480* and will inherit @old children.481*482* refcount @new for list, put @old list refcount483*484* Requires: namespace list lock be held, or list not be shared485*/486static void __replace_profile(struct aa_profile *old, struct aa_profile *new)487{488struct aa_policy *policy;489struct aa_profile *child, *tmp;490491if (old->parent)492policy = &old->parent->base;493else494policy = &old->ns->base;495496/* released when @new is freed */497new->parent = aa_get_profile(old->parent);498new->ns = aa_get_namespace(old->ns);499new->sid = old->sid;500__list_add_profile(&policy->profiles, new);501/* inherit children */502list_for_each_entry_safe(child, tmp, &old->base.profiles, base.list) {503aa_put_profile(child->parent);504child->parent = aa_get_profile(new);505/* list refcount transferred to @new*/506list_move(&child->base.list, &new->base.profiles);507}508509/* released by free_profile */510old->replacedby = aa_get_profile(new);511__list_remove_profile(old);512}513514static void __profile_list_release(struct list_head *head);515516/**517* __remove_profile - remove old profile, and children518* @profile: profile to be replaced (NOT NULL)519*520* Requires: namespace list lock be held, or list not be shared521*/522static void __remove_profile(struct aa_profile *profile)523{524/* release any children lists first */525__profile_list_release(&profile->base.profiles);526/* released by free_profile */527profile->replacedby = aa_get_profile(profile->ns->unconfined);528__list_remove_profile(profile);529}530531/**532* __profile_list_release - remove all profiles on the list and put refs533* @head: list of profiles (NOT NULL)534*535* Requires: namespace lock be held536*/537static void __profile_list_release(struct list_head *head)538{539struct aa_profile *profile, *tmp;540list_for_each_entry_safe(profile, tmp, head, base.list)541__remove_profile(profile);542}543544static void __ns_list_release(struct list_head *head);545546/**547* destroy_namespace - remove everything contained by @ns548* @ns: namespace to have it contents removed (NOT NULL)549*/550static void destroy_namespace(struct aa_namespace *ns)551{552if (!ns)553return;554555write_lock(&ns->lock);556/* release all profiles in this namespace */557__profile_list_release(&ns->base.profiles);558559/* release all sub namespaces */560__ns_list_release(&ns->sub_ns);561562write_unlock(&ns->lock);563}564565/**566* __remove_namespace - remove a namespace and all its children567* @ns: namespace to be removed (NOT NULL)568*569* Requires: ns->parent->lock be held and ns removed from parent.570*/571static void __remove_namespace(struct aa_namespace *ns)572{573struct aa_profile *unconfined = ns->unconfined;574575/* remove ns from namespace list */576list_del_init(&ns->base.list);577578/*579* break the ns, unconfined profile cyclic reference and forward580* all new unconfined profiles requests to the parent namespace581* This will result in all confined tasks that have a profile582* being removed, inheriting the parent->unconfined profile.583*/584if (ns->parent)585ns->unconfined = aa_get_profile(ns->parent->unconfined);586587destroy_namespace(ns);588589/* release original ns->unconfined ref */590aa_put_profile(unconfined);591/* release ns->base.list ref, from removal above */592aa_put_namespace(ns);593}594595/**596* __ns_list_release - remove all profile namespaces on the list put refs597* @head: list of profile namespaces (NOT NULL)598*599* Requires: namespace lock be held600*/601static void __ns_list_release(struct list_head *head)602{603struct aa_namespace *ns, *tmp;604list_for_each_entry_safe(ns, tmp, head, base.list)605__remove_namespace(ns);606607}608609/**610* aa_alloc_root_ns - allocate the root profile namespace611*612* Returns: %0 on success else error613*614*/615int __init aa_alloc_root_ns(void)616{617/* released by aa_free_root_ns - used as list ref*/618root_ns = alloc_namespace(NULL, "root");619if (!root_ns)620return -ENOMEM;621622return 0;623}624625/**626* aa_free_root_ns - free the root profile namespace627*/628void __init aa_free_root_ns(void)629{630struct aa_namespace *ns = root_ns;631root_ns = NULL;632633destroy_namespace(ns);634aa_put_namespace(ns);635}636637/**638* aa_alloc_profile - allocate, initialize and return a new profile639* @hname: name of the profile (NOT NULL)640*641* Returns: refcount profile or NULL on failure642*/643struct aa_profile *aa_alloc_profile(const char *hname)644{645struct aa_profile *profile;646647/* freed by free_profile - usually through aa_put_profile */648profile = kzalloc(sizeof(*profile), GFP_KERNEL);649if (!profile)650return NULL;651652if (!policy_init(&profile->base, NULL, hname)) {653kzfree(profile);654return NULL;655}656657/* refcount released by caller */658return profile;659}660661/**662* aa_new_null_profile - create a new null-X learning profile663* @parent: profile that caused this profile to be created (NOT NULL)664* @hat: true if the null- learning profile is a hat665*666* Create a null- complain mode profile used in learning mode. The name of667* the profile is unique and follows the format of parent//null-sid.668*669* null profiles are added to the profile list but the list does not670* hold a count on them so that they are automatically released when671* not in use.672*673* Returns: new refcounted profile else NULL on failure674*/675struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat)676{677struct aa_profile *profile = NULL;678char *name;679u32 sid = aa_alloc_sid();680681/* freed below */682name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, GFP_KERNEL);683if (!name)684goto fail;685sprintf(name, "%s//null-%x", parent->base.hname, sid);686687profile = aa_alloc_profile(name);688kfree(name);689if (!profile)690goto fail;691692profile->sid = sid;693profile->mode = APPARMOR_COMPLAIN;694profile->flags = PFLAG_NULL;695if (hat)696profile->flags |= PFLAG_HAT;697698/* released on free_profile */699profile->parent = aa_get_profile(parent);700profile->ns = aa_get_namespace(parent->ns);701702write_lock(&profile->ns->lock);703__list_add_profile(&parent->base.profiles, profile);704write_unlock(&profile->ns->lock);705706/* refcount released by caller */707return profile;708709fail:710aa_free_sid(sid);711return NULL;712}713714/**715* free_profile - free a profile716* @profile: the profile to free (MAYBE NULL)717*718* Free a profile, its hats and null_profile. All references to the profile,719* its hats and null_profile must have been put.720*721* If the profile was referenced from a task context, free_profile() will722* be called from an rcu callback routine, so we must not sleep here.723*/724static void free_profile(struct aa_profile *profile)725{726AA_DEBUG("%s(%p)\n", __func__, profile);727728if (!profile)729return;730731if (!list_empty(&profile->base.list)) {732AA_ERROR("%s: internal error, "733"profile '%s' still on ns list\n",734__func__, profile->base.name);735BUG();736}737738/* free children profiles */739policy_destroy(&profile->base);740aa_put_profile(profile->parent);741742aa_put_namespace(profile->ns);743kzfree(profile->rename);744745aa_free_file_rules(&profile->file);746aa_free_cap_rules(&profile->caps);747aa_free_rlimit_rules(&profile->rlimits);748749aa_free_sid(profile->sid);750aa_put_dfa(profile->xmatch);751752aa_put_profile(profile->replacedby);753754kzfree(profile);755}756757/**758* aa_free_profile_kref - free aa_profile by kref (called by aa_put_profile)759* @kr: kref callback for freeing of a profile (NOT NULL)760*/761void aa_free_profile_kref(struct kref *kref)762{763struct aa_profile *p = container_of(kref, struct aa_profile,764base.count);765766free_profile(p);767}768769/* TODO: profile accounting - setup in remove */770771/**772* __find_child - find a profile on @head list with a name matching @name773* @head: list to search (NOT NULL)774* @name: name of profile (NOT NULL)775*776* Requires: ns lock protecting list be held777*778* Returns: unrefcounted profile ptr, or NULL if not found779*/780static struct aa_profile *__find_child(struct list_head *head, const char *name)781{782return (struct aa_profile *)__policy_find(head, name);783}784785/**786* __strn_find_child - find a profile on @head list using substring of @name787* @head: list to search (NOT NULL)788* @name: name of profile (NOT NULL)789* @len: length of @name substring to match790*791* Requires: ns lock protecting list be held792*793* Returns: unrefcounted profile ptr, or NULL if not found794*/795static struct aa_profile *__strn_find_child(struct list_head *head,796const char *name, int len)797{798return (struct aa_profile *)__policy_strn_find(head, name, len);799}800801/**802* aa_find_child - find a profile by @name in @parent803* @parent: profile to search (NOT NULL)804* @name: profile name to search for (NOT NULL)805*806* Returns: a refcounted profile or NULL if not found807*/808struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name)809{810struct aa_profile *profile;811812read_lock(&parent->ns->lock);813profile = aa_get_profile(__find_child(&parent->base.profiles, name));814read_unlock(&parent->ns->lock);815816/* refcount released by caller */817return profile;818}819820/**821* __lookup_parent - lookup the parent of a profile of name @hname822* @ns: namespace to lookup profile in (NOT NULL)823* @hname: hierarchical profile name to find parent of (NOT NULL)824*825* Lookups up the parent of a fully qualified profile name, the profile826* that matches hname does not need to exist, in general this827* is used to load a new profile.828*829* Requires: ns->lock be held830*831* Returns: unrefcounted policy or NULL if not found832*/833static struct aa_policy *__lookup_parent(struct aa_namespace *ns,834const char *hname)835{836struct aa_policy *policy;837struct aa_profile *profile = NULL;838char *split;839840policy = &ns->base;841842for (split = strstr(hname, "//"); split;) {843profile = __strn_find_child(&policy->profiles, hname,844split - hname);845if (!profile)846return NULL;847policy = &profile->base;848hname = split + 2;849split = strstr(hname, "//");850}851if (!profile)852return &ns->base;853return &profile->base;854}855856/**857* __lookup_profile - lookup the profile matching @hname858* @base: base list to start looking up profile name from (NOT NULL)859* @hname: hierarchical profile name (NOT NULL)860*861* Requires: ns->lock be held862*863* Returns: unrefcounted profile pointer or NULL if not found864*865* Do a relative name lookup, recursing through profile tree.866*/867static struct aa_profile *__lookup_profile(struct aa_policy *base,868const char *hname)869{870struct aa_profile *profile = NULL;871char *split;872873for (split = strstr(hname, "//"); split;) {874profile = __strn_find_child(&base->profiles, hname,875split - hname);876if (!profile)877return NULL;878879base = &profile->base;880hname = split + 2;881split = strstr(hname, "//");882}883884profile = __find_child(&base->profiles, hname);885886return profile;887}888889/**890* aa_lookup_profile - find a profile by its full or partial name891* @ns: the namespace to start from (NOT NULL)892* @hname: name to do lookup on. Does not contain namespace prefix (NOT NULL)893*894* Returns: refcounted profile or NULL if not found895*/896struct aa_profile *aa_lookup_profile(struct aa_namespace *ns, const char *hname)897{898struct aa_profile *profile;899900read_lock(&ns->lock);901profile = aa_get_profile(__lookup_profile(&ns->base, hname));902read_unlock(&ns->lock);903904/* refcount released by caller */905return profile;906}907908/**909* replacement_allowed - test to see if replacement is allowed910* @profile: profile to test if it can be replaced (MAYBE NULL)911* @noreplace: true if replacement shouldn't be allowed but addition is okay912* @info: Returns - info about why replacement failed (NOT NULL)913*914* Returns: %0 if replacement allowed else error code915*/916static int replacement_allowed(struct aa_profile *profile, int noreplace,917const char **info)918{919if (profile) {920if (profile->flags & PFLAG_IMMUTABLE) {921*info = "cannot replace immutible profile";922return -EPERM;923} else if (noreplace) {924*info = "profile already exists";925return -EEXIST;926}927}928return 0;929}930931/**932* __add_new_profile - simple wrapper around __list_add_profile933* @ns: namespace that profile is being added to (NOT NULL)934* @policy: the policy container to add the profile to (NOT NULL)935* @profile: profile to add (NOT NULL)936*937* add a profile to a list and do other required basic allocations938*/939static void __add_new_profile(struct aa_namespace *ns, struct aa_policy *policy,940struct aa_profile *profile)941{942if (policy != &ns->base)943/* released on profile replacement or free_profile */944profile->parent = aa_get_profile((struct aa_profile *) policy);945__list_add_profile(&policy->profiles, profile);946/* released on free_profile */947profile->sid = aa_alloc_sid();948profile->ns = aa_get_namespace(ns);949}950951/**952* aa_audit_policy - Do auditing of policy changes953* @op: policy operation being performed954* @gfp: memory allocation flags955* @name: name of profile being manipulated (NOT NULL)956* @info: any extra information to be audited (MAYBE NULL)957* @error: error code958*959* Returns: the error to be returned after audit is done960*/961static int audit_policy(int op, gfp_t gfp, const char *name, const char *info,962int error)963{964struct common_audit_data sa;965COMMON_AUDIT_DATA_INIT(&sa, NONE);966sa.aad.op = op;967sa.aad.name = name;968sa.aad.info = info;969sa.aad.error = error;970971return aa_audit(AUDIT_APPARMOR_STATUS, __aa_current_profile(), gfp,972&sa, NULL);973}974975/**976* aa_may_manage_policy - can the current task manage policy977* @op: the policy manipulation operation being done978*979* Returns: true if the task is allowed to manipulate policy980*/981bool aa_may_manage_policy(int op)982{983/* check if loading policy is locked out */984if (aa_g_lock_policy) {985audit_policy(op, GFP_KERNEL, NULL, "policy_locked", -EACCES);986return 0;987}988989if (!capable(CAP_MAC_ADMIN)) {990audit_policy(op, GFP_KERNEL, NULL, "not policy admin", -EACCES);991return 0;992}993994return 1;995}996997/**998* aa_replace_profiles - replace profile(s) on the profile list999* @udata: serialized data stream (NOT NULL)1000* @size: size of the serialized data stream1001* @noreplace: true if only doing addition, no replacement allowed1002*1003* unpack and replace a profile on the profile list and uses of that profile1004* by any aa_task_cxt. If the profile does not exist on the profile list1005* it is added.1006*1007* Returns: size of data consumed else error code on failure.1008*/1009ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)1010{1011struct aa_policy *policy;1012struct aa_profile *old_profile = NULL, *new_profile = NULL;1013struct aa_profile *rename_profile = NULL;1014struct aa_namespace *ns = NULL;1015const char *ns_name, *name = NULL, *info = NULL;1016int op = OP_PROF_REPL;1017ssize_t error;10181019/* released below */1020new_profile = aa_unpack(udata, size, &ns_name);1021if (IS_ERR(new_profile)) {1022error = PTR_ERR(new_profile);1023new_profile = NULL;1024goto fail;1025}10261027/* released below */1028ns = aa_prepare_namespace(ns_name);1029if (!ns) {1030info = "failed to prepare namespace";1031error = -ENOMEM;1032name = ns_name;1033goto fail;1034}10351036name = new_profile->base.hname;10371038write_lock(&ns->lock);1039/* no ref on policy only use inside lock */1040policy = __lookup_parent(ns, new_profile->base.hname);10411042if (!policy) {1043info = "parent does not exist";1044error = -ENOENT;1045goto audit;1046}10471048old_profile = __find_child(&policy->profiles, new_profile->base.name);1049/* released below */1050aa_get_profile(old_profile);10511052if (new_profile->rename) {1053rename_profile = __lookup_profile(&ns->base,1054new_profile->rename);1055/* released below */1056aa_get_profile(rename_profile);10571058if (!rename_profile) {1059info = "profile to rename does not exist";1060name = new_profile->rename;1061error = -ENOENT;1062goto audit;1063}1064}10651066error = replacement_allowed(old_profile, noreplace, &info);1067if (error)1068goto audit;10691070error = replacement_allowed(rename_profile, noreplace, &info);1071if (error)1072goto audit;10731074audit:1075if (!old_profile && !rename_profile)1076op = OP_PROF_LOAD;10771078error = audit_policy(op, GFP_ATOMIC, name, info, error);10791080if (!error) {1081if (rename_profile)1082__replace_profile(rename_profile, new_profile);1083if (old_profile) {1084/* when there are both rename and old profiles1085* inherit old profiles sid1086*/1087if (rename_profile)1088aa_free_sid(new_profile->sid);1089__replace_profile(old_profile, new_profile);1090}1091if (!(old_profile || rename_profile))1092__add_new_profile(ns, policy, new_profile);1093}1094write_unlock(&ns->lock);10951096out:1097aa_put_namespace(ns);1098aa_put_profile(rename_profile);1099aa_put_profile(old_profile);1100aa_put_profile(new_profile);1101if (error)1102return error;1103return size;11041105fail:1106error = audit_policy(op, GFP_KERNEL, name, info, error);1107goto out;1108}11091110/**1111* aa_remove_profiles - remove profile(s) from the system1112* @fqname: name of the profile or namespace to remove (NOT NULL)1113* @size: size of the name1114*1115* Remove a profile or sub namespace from the current namespace, so that1116* they can not be found anymore and mark them as replaced by unconfined1117*1118* NOTE: removing confinement does not restore rlimits to preconfinemnet values1119*1120* Returns: size of data consume else error code if fails1121*/1122ssize_t aa_remove_profiles(char *fqname, size_t size)1123{1124struct aa_namespace *root, *ns = NULL;1125struct aa_profile *profile = NULL;1126const char *name = fqname, *info = NULL;1127ssize_t error = 0;11281129if (*fqname == 0) {1130info = "no profile specified";1131error = -ENOENT;1132goto fail;1133}11341135root = aa_current_profile()->ns;11361137if (fqname[0] == ':') {1138char *ns_name;1139name = aa_split_fqname(fqname, &ns_name);1140if (ns_name) {1141/* released below */1142ns = aa_find_namespace(root, ns_name);1143if (!ns) {1144info = "namespace does not exist";1145error = -ENOENT;1146goto fail;1147}1148}1149} else1150/* released below */1151ns = aa_get_namespace(root);11521153if (!name) {1154/* remove namespace - can only happen if fqname[0] == ':' */1155write_lock(&ns->parent->lock);1156__remove_namespace(ns);1157write_unlock(&ns->parent->lock);1158} else {1159/* remove profile */1160write_lock(&ns->lock);1161profile = aa_get_profile(__lookup_profile(&ns->base, name));1162if (!profile) {1163error = -ENOENT;1164info = "profile does not exist";1165goto fail_ns_lock;1166}1167name = profile->base.hname;1168__remove_profile(profile);1169write_unlock(&ns->lock);1170}11711172/* don't fail removal if audit fails */1173(void) audit_policy(OP_PROF_RM, GFP_KERNEL, name, info, error);1174aa_put_namespace(ns);1175aa_put_profile(profile);1176return size;11771178fail_ns_lock:1179write_unlock(&ns->lock);1180aa_put_namespace(ns);11811182fail:1183(void) audit_policy(OP_PROF_RM, GFP_KERNEL, name, info, error);1184return error;1185}118611871188