/* SPDX-License-Identifier: GPL-2.0-only */1/*2* AppArmor security module3*4* This file contains AppArmor policy definitions.5*6* Copyright (C) 1998-2008 Novell/SUSE7* Copyright 2009-2010 Canonical Ltd.8*/910#ifndef __AA_POLICY_H11#define __AA_POLICY_H1213#include <linux/capability.h>14#include <linux/cred.h>15#include <linux/kref.h>16#include <linux/rhashtable.h>17#include <linux/sched.h>18#include <linux/slab.h>19#include <linux/socket.h>2021#include "apparmor.h"22#include "audit.h"23#include "capability.h"24#include "domain.h"25#include "file.h"26#include "lib.h"27#include "label.h"28#include "net.h"29#include "perms.h"30#include "resource.h"313233struct aa_ns;3435extern int unprivileged_userns_apparmor_policy;36extern int aa_unprivileged_unconfined_restricted;3738extern const char *const aa_profile_mode_names[];39#define APPARMOR_MODE_NAMES_MAX_INDEX 44041#define PROFILE_MODE(_profile, _mode) \42((aa_g_profile_mode == (_mode)) || \43((_profile)->mode == (_mode)))4445#define COMPLAIN_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_COMPLAIN)4647#define USER_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_USER)4849#define KILL_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_KILL)5051#define PROFILE_IS_HAT(_profile) ((_profile)->label.flags & FLAG_HAT)5253#define CHECK_DEBUG1(_profile) ((_profile)->label.flags & FLAG_DEBUG1)5455#define CHECK_DEBUG2(_profile) ((_profile)->label.flags & FLAG_DEBUG2)5657#define profile_is_stale(_profile) (label_is_stale(&(_profile)->label))5859#define on_list_rcu(X) (!list_empty(X) && (X)->prev != LIST_POISON2)6061/* flags in the dfa accept2 table */62enum dfa_accept_flags {63ACCEPT_FLAG_OWNER = 1,64};6566/*67* FIXME: currently need a clean way to replace and remove profiles as a68* set. It should be done at the namespace level.69* Either, with a set of profiles loaded at the namespace level or via70* a mark and remove marked interface.71*/72enum profile_mode {73APPARMOR_ENFORCE, /* enforce access rules */74APPARMOR_COMPLAIN, /* allow and log access violations */75APPARMOR_KILL, /* kill task on access violation */76APPARMOR_UNCONFINED, /* profile set to unconfined */77APPARMOR_USER, /* modified complain mode to userspace */78};798081/* struct aa_policydb - match engine for a policy82* count: refcount for the pdb83* dfa: dfa pattern match84* perms: table of permissions85* strs: table of strings, index by x86* start: set of start states for the different classes of data87*/88struct aa_policydb {89struct kref count;90struct aa_dfa *dfa;91struct {92struct aa_perms *perms;93u32 size;94};95struct aa_str_table trans;96aa_state_t start[AA_CLASS_LAST + 1];97};9899extern struct aa_policydb *nullpdb;100101struct aa_policydb *aa_alloc_pdb(gfp_t gfp);102void aa_pdb_free_kref(struct kref *kref);103104/**105* aa_get_pdb - increment refcount on @pdb106* @pdb: policydb (MAYBE NULL)107*108* Returns: pointer to @pdb if @pdb is NULL will return NULL109* Requires: @pdb must be held with valid refcount when called110*/111static inline struct aa_policydb *aa_get_pdb(struct aa_policydb *pdb)112{113if (pdb)114kref_get(&(pdb->count));115116return pdb;117}118119/**120* aa_put_pdb - put a pdb refcount121* @pdb: pdb to put refcount (MAYBE NULL)122*123* Requires: if @pdb != NULL that a valid refcount be held124*/125static inline void aa_put_pdb(struct aa_policydb *pdb)126{127if (pdb)128kref_put(&pdb->count, aa_pdb_free_kref);129}130131/* lookup perm that doesn't have and object conditional */132static inline struct aa_perms *aa_lookup_perms(struct aa_policydb *policy,133aa_state_t state)134{135unsigned int index = ACCEPT_TABLE(policy->dfa)[state];136137if (!(policy->perms))138return &default_perms;139140return &(policy->perms[index]);141}142143/* struct aa_data - generic data structure144* key: name for retrieving this data145* size: size of data in bytes146* data: binary data147* head: reserved for rhashtable148*/149struct aa_data {150char *key;151u32 size;152char *data;153struct rhash_head head;154};155156/* struct aa_ruleset - data covering mediation rules157* @list: list the rule is on158* @size: the memory consumed by this ruleset159* @policy: general match rules governing policy160* @file: The set of rules governing basic file access and domain transitions161* @caps: capabilities for the profile162* @rlimits: rlimits for the profile163* @secmark_count: number of secmark entries164* @secmark: secmark label match info165*/166struct aa_ruleset {167int size;168169/* TODO: merge policy and file */170struct aa_policydb *policy;171struct aa_policydb *file;172struct aa_caps caps;173174struct aa_rlimit rlimits;175176int secmark_count;177struct aa_secmark *secmark;178};179180181/* struct aa_attachment - data and rules for a profiles attachment182* @list:183* @xmatch_str: human readable attachment string184* @xmatch: optional extended matching for unconfined executables names185* @xmatch_len: xmatch prefix len, used to determine xmatch priority186* @xattr_count: number of xattrs in table187* @xattrs: table of xattrs188*/189struct aa_attachment {190const char *xmatch_str;191struct aa_policydb *xmatch;192unsigned int xmatch_len;193int xattr_count;194char **xattrs;195};196197/* struct aa_profile - basic confinement data198* @base - base components of the profile (name, refcount, lists, lock ...)199* @parent: parent of profile200* @ns: namespace the profile is in201* @rename: optional profile name that this profile renamed202*203* @audit: the auditing mode of the profile204* @mode: the enforcement mode of the profile205* @path_flags: flags controlling path generation behavior206* @signal: the signal that should be used when kill is used207* @disconnected: what to prepend if attach_disconnected is specified208* @attach: attachment rules for the profile209* @rules: rules to be enforced210*211* learning_cache: the accesses learned in complain mode212* raw_data: rawdata of the loaded profile policy213* hash: cryptographic hash of the profile214* @dents: dentries for the profiles file entries in apparmorfs215* @dirname: name of the profile dir in apparmorfs216* @dents: set of dentries associated with the profile217* @data: hashtable for free-form policy aa_data218* @label - label this profile is an extension of219* @rules - label with the rule vec on its end220*221* The AppArmor profile contains the basic confinement data. Each profile222* has a name, and exists in a namespace. The @name and @exec_match are223* used to determine profile attachment against unconfined tasks. All other224* attachments are determined by profile X transition rules.225*226* Profiles have a hierarchy where hats and children profiles keep227* a reference to their parent.228*229* Profile names can not begin with a : and can not contain the \0230* character. If a profile name begins with / it will be considered when231* determining profile attachment on "unconfined" tasks.232*/233struct aa_profile {234struct aa_policy base;235struct aa_profile __rcu *parent;236237struct aa_ns *ns;238const char *rename;239240enum audit_mode audit;241long mode;242u32 path_flags;243int signal;244const char *disconnected;245246struct aa_attachment attach;247248struct aa_loaddata *rawdata;249unsigned char *hash;250char *dirname;251struct dentry *dents[AAFS_PROF_SIZEOF];252struct rhashtable *data;253254int n_rules;255/* special - variable length must be last entry in profile */256struct aa_label label;257};258259extern enum profile_mode aa_g_profile_mode;260261#define AA_MAY_LOAD_POLICY AA_MAY_APPEND262#define AA_MAY_REPLACE_POLICY AA_MAY_WRITE263#define AA_MAY_REMOVE_POLICY AA_MAY_DELETE264265#define profiles_ns(P) ((P)->ns)266#define name_is_shared(A, B) ((A)->hname && (A)->hname == (B)->hname)267268struct aa_ruleset *aa_alloc_ruleset(gfp_t gfp);269struct aa_profile *aa_alloc_profile(const char *name, struct aa_proxy *proxy,270gfp_t gfp);271struct aa_profile *aa_alloc_null(struct aa_profile *parent, const char *name,272gfp_t gfp);273struct aa_profile *aa_new_learning_profile(struct aa_profile *parent, bool hat,274const char *base, gfp_t gfp);275void aa_free_profile(struct aa_profile *profile);276struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name);277struct aa_profile *aa_lookupn_profile(struct aa_ns *ns, const char *hname,278size_t n);279struct aa_profile *aa_fqlookupn_profile(struct aa_label *base,280const char *fqname, size_t n);281282ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_label *label,283u32 mask, struct aa_loaddata *udata);284ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_label *label,285char *name, size_t size);286void __aa_profile_list_release(struct list_head *head);287288#define profile_unconfined(X) ((X)->mode == APPARMOR_UNCONFINED)289290/**291* aa_get_newest_profile - simple wrapper fn to wrap the label version292* @p: profile (NOT NULL)293*294* Returns refcount to newest version of the profile (maybe @p)295*296* Requires: @p must be held with a valid refcount297*/298static inline struct aa_profile *aa_get_newest_profile(struct aa_profile *p)299{300return labels_profile(aa_get_newest_label(&p->label));301}302303static inline aa_state_t RULE_MEDIATES(struct aa_ruleset *rules,304unsigned char class)305{306if (class <= AA_CLASS_LAST)307return rules->policy->start[class];308else309return aa_dfa_match_len(rules->policy->dfa,310rules->policy->start[0], &class, 1);311}312313static inline aa_state_t RULE_MEDIATES_v9NET(struct aa_ruleset *rules)314{315return RULE_MEDIATES(rules, AA_CLASS_NETV9);316}317318static inline aa_state_t RULE_MEDIATES_NET(struct aa_ruleset *rules)319{320/* can not use RULE_MEDIATE_v9AF here, because AF match fail321* can not be distiguished from class match fail, and we only322* fallback to checking older class on class match failure323*/324aa_state_t state = RULE_MEDIATES(rules, AA_CLASS_NETV9);325326/* fallback and check v7/8 if v9 is NOT mediated */327if (!state)328state = RULE_MEDIATES(rules, AA_CLASS_NET);329330return state;331}332333334void aa_compute_profile_mediates(struct aa_profile *profile);335static inline bool profile_mediates(struct aa_profile *profile,336unsigned char class)337{338return label_mediates(&profile->label, class);339}340341static inline bool profile_mediates_safe(struct aa_profile *profile,342unsigned char class)343{344return label_mediates_safe(&profile->label, class);345}346347/**348* aa_get_profile - increment refcount on profile @p349* @p: profile (MAYBE NULL)350*351* Returns: pointer to @p if @p is NULL will return NULL352* Requires: @p must be held with valid refcount when called353*/354static inline struct aa_profile *aa_get_profile(struct aa_profile *p)355{356if (p)357kref_get(&(p->label.count));358359return p;360}361362/**363* aa_get_profile_not0 - increment refcount on profile @p found via lookup364* @p: profile (MAYBE NULL)365*366* Returns: pointer to @p if @p is NULL will return NULL367* Requires: @p must be held with valid refcount when called368*/369static inline struct aa_profile *aa_get_profile_not0(struct aa_profile *p)370{371if (p && kref_get_unless_zero(&p->label.count))372return p;373374return NULL;375}376377/**378* aa_get_profile_rcu - increment a refcount profile that can be replaced379* @p: pointer to profile that can be replaced (NOT NULL)380*381* Returns: pointer to a refcounted profile.382* else NULL if no profile383*/384static inline struct aa_profile *aa_get_profile_rcu(struct aa_profile __rcu **p)385{386struct aa_profile *c;387388rcu_read_lock();389do {390c = rcu_dereference(*p);391} while (c && !kref_get_unless_zero(&c->label.count));392rcu_read_unlock();393394return c;395}396397/**398* aa_put_profile - decrement refcount on profile @p399* @p: profile (MAYBE NULL)400*/401static inline void aa_put_profile(struct aa_profile *p)402{403if (p)404kref_put(&p->label.count, aa_label_kref);405}406407static inline int AUDIT_MODE(struct aa_profile *profile)408{409if (aa_g_audit != AUDIT_NORMAL)410return aa_g_audit;411412return profile->audit;413}414415bool aa_policy_view_capable(const struct cred *subj_cred,416struct aa_label *label, struct aa_ns *ns);417bool aa_policy_admin_capable(const struct cred *subj_cred,418struct aa_label *label, struct aa_ns *ns);419int aa_may_manage_policy(const struct cred *subj_cred,420struct aa_label *label, struct aa_ns *ns,421u32 mask);422bool aa_current_policy_view_capable(struct aa_ns *ns);423bool aa_current_policy_admin_capable(struct aa_ns *ns);424425#endif /* __AA_POLICY_H */426427428