linux/security/apparmor/include/policy.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * AppArmor security module
   4 *
   5 * This file contains AppArmor policy definitions.
   6 *
   7 * Copyright (C) 1998-2008 Novell/SUSE
   8 * Copyright 2009-2010 Canonical Ltd.
   9 */
  10
  11#ifndef __AA_POLICY_H
  12#define __AA_POLICY_H
  13
  14#include <linux/capability.h>
  15#include <linux/cred.h>
  16#include <linux/kref.h>
  17#include <linux/rhashtable.h>
  18#include <linux/sched.h>
  19#include <linux/slab.h>
  20#include <linux/socket.h>
  21
  22#include "apparmor.h"
  23#include "audit.h"
  24#include "capability.h"
  25#include "domain.h"
  26#include "file.h"
  27#include "lib.h"
  28#include "label.h"
  29#include "net.h"
  30#include "perms.h"
  31#include "resource.h"
  32
  33
  34struct aa_ns;
  35
  36extern int unprivileged_userns_apparmor_policy;
  37
  38extern const char *const aa_profile_mode_names[];
  39#define APPARMOR_MODE_NAMES_MAX_INDEX 4
  40
  41#define PROFILE_MODE(_profile, _mode)           \
  42        ((aa_g_profile_mode == (_mode)) ||      \
  43         ((_profile)->mode == (_mode)))
  44
  45#define COMPLAIN_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_COMPLAIN)
  46
  47#define KILL_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_KILL)
  48
  49#define PROFILE_IS_HAT(_profile) ((_profile)->label.flags & FLAG_HAT)
  50
  51#define profile_is_stale(_profile) (label_is_stale(&(_profile)->label))
  52
  53#define on_list_rcu(X) (!list_empty(X) && (X)->prev != LIST_POISON2)
  54
  55/*
  56 * FIXME: currently need a clean way to replace and remove profiles as a
  57 * set.  It should be done at the namespace level.
  58 * Either, with a set of profiles loaded at the namespace level or via
  59 * a mark and remove marked interface.
  60 */
  61enum profile_mode {
  62        APPARMOR_ENFORCE,       /* enforce access rules */
  63        APPARMOR_COMPLAIN,      /* allow and log access violations */
  64        APPARMOR_KILL,          /* kill task on access violation */
  65        APPARMOR_UNCONFINED,    /* profile set to unconfined */
  66};
  67
  68
  69/* struct aa_policydb - match engine for a policy
  70 * dfa: dfa pattern match
  71 * start: set of start states for the different classes of data
  72 */
  73struct aa_policydb {
  74        /* Generic policy DFA specific rule types will be subsections of it */
  75        struct aa_dfa *dfa;
  76        unsigned int start[AA_CLASS_LAST + 1];
  77
  78};
  79
  80/* struct aa_data - generic data structure
  81 * key: name for retrieving this data
  82 * size: size of data in bytes
  83 * data: binary data
  84 * head: reserved for rhashtable
  85 */
  86struct aa_data {
  87        char *key;
  88        u32 size;
  89        char *data;
  90        struct rhash_head head;
  91};
  92
  93
  94/* struct aa_profile - basic confinement data
  95 * @base - base components of the profile (name, refcount, lists, lock ...)
  96 * @label - label this profile is an extension of
  97 * @parent: parent of profile
  98 * @ns: namespace the profile is in
  99 * @rename: optional profile name that this profile renamed
 100 * @attach: human readable attachment string
 101 * @xmatch: optional extended matching for unconfined executables names
 102 * @xmatch_len: xmatch prefix len, used to determine xmatch priority
 103 * @audit: the auditing mode of the profile
 104 * @mode: the enforcement mode of the profile
 105 * @path_flags: flags controlling path generation behavior
 106 * @disconnected: what to prepend if attach_disconnected is specified
 107 * @size: the memory consumed by this profiles rules
 108 * @policy: general match rules governing policy
 109 * @file: The set of rules governing basic file access and domain transitions
 110 * @caps: capabilities for the profile
 111 * @rlimits: rlimits for the profile
 112 *
 113 * @dents: dentries for the profiles file entries in apparmorfs
 114 * @dirname: name of the profile dir in apparmorfs
 115 * @data: hashtable for free-form policy aa_data
 116 *
 117 * The AppArmor profile contains the basic confinement data.  Each profile
 118 * has a name, and exists in a namespace.  The @name and @exec_match are
 119 * used to determine profile attachment against unconfined tasks.  All other
 120 * attachments are determined by profile X transition rules.
 121 *
 122 * Profiles have a hierarchy where hats and children profiles keep
 123 * a reference to their parent.
 124 *
 125 * Profile names can not begin with a : and can not contain the \0
 126 * character.  If a profile name begins with / it will be considered when
 127 * determining profile attachment on "unconfined" tasks.
 128 */
 129struct aa_profile {
 130        struct aa_policy base;
 131        struct aa_profile __rcu *parent;
 132
 133        struct aa_ns *ns;
 134        const char *rename;
 135
 136        const char *attach;
 137        struct aa_dfa *xmatch;
 138        int xmatch_len;
 139        enum audit_mode audit;
 140        long mode;
 141        u32 path_flags;
 142        const char *disconnected;
 143        int size;
 144
 145        struct aa_policydb policy;
 146        struct aa_file_rules file;
 147        struct aa_caps caps;
 148
 149        int xattr_count;
 150        char **xattrs;
 151
 152        struct aa_rlimit rlimits;
 153
 154        int secmark_count;
 155        struct aa_secmark *secmark;
 156
 157        struct aa_loaddata *rawdata;
 158        unsigned char *hash;
 159        char *dirname;
 160        struct dentry *dents[AAFS_PROF_SIZEOF];
 161        struct rhashtable *data;
 162        struct aa_label label;
 163};
 164
 165extern enum profile_mode aa_g_profile_mode;
 166
 167#define AA_MAY_LOAD_POLICY      AA_MAY_APPEND
 168#define AA_MAY_REPLACE_POLICY   AA_MAY_WRITE
 169#define AA_MAY_REMOVE_POLICY    AA_MAY_DELETE
 170
 171#define profiles_ns(P) ((P)->ns)
 172#define name_is_shared(A, B) ((A)->hname && (A)->hname == (B)->hname)
 173
 174void aa_add_profile(struct aa_policy *common, struct aa_profile *profile);
 175
 176
 177void aa_free_proxy_kref(struct kref *kref);
 178struct aa_profile *aa_alloc_profile(const char *name, struct aa_proxy *proxy,
 179                                    gfp_t gfp);
 180struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
 181                                       const char *base, gfp_t gfp);
 182void aa_free_profile(struct aa_profile *profile);
 183void aa_free_profile_kref(struct kref *kref);
 184struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name);
 185struct aa_profile *aa_lookupn_profile(struct aa_ns *ns, const char *hname,
 186                                      size_t n);
 187struct aa_profile *aa_lookup_profile(struct aa_ns *ns, const char *name);
 188struct aa_profile *aa_fqlookupn_profile(struct aa_label *base,
 189                                        const char *fqname, size_t n);
 190struct aa_profile *aa_match_profile(struct aa_ns *ns, const char *name);
 191
 192ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_label *label,
 193                            u32 mask, struct aa_loaddata *udata);
 194ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_label *label,
 195                           char *name, size_t size);
 196void __aa_profile_list_release(struct list_head *head);
 197
 198#define PROF_ADD 1
 199#define PROF_REPLACE 0
 200
 201#define profile_unconfined(X) ((X)->mode == APPARMOR_UNCONFINED)
 202
 203/**
 204 * aa_get_newest_profile - simple wrapper fn to wrap the label version
 205 * @p: profile (NOT NULL)
 206 *
 207 * Returns refcount to newest version of the profile (maybe @p)
 208 *
 209 * Requires: @p must be held with a valid refcount
 210 */
 211static inline struct aa_profile *aa_get_newest_profile(struct aa_profile *p)
 212{
 213        return labels_profile(aa_get_newest_label(&p->label));
 214}
 215
 216static inline unsigned int PROFILE_MEDIATES(struct aa_profile *profile,
 217                                            unsigned char class)
 218{
 219        if (class <= AA_CLASS_LAST)
 220                return profile->policy.start[class];
 221        else
 222                return aa_dfa_match_len(profile->policy.dfa,
 223                                        profile->policy.start[0], &class, 1);
 224}
 225
 226static inline unsigned int PROFILE_MEDIATES_AF(struct aa_profile *profile,
 227                                               u16 AF) {
 228        unsigned int state = PROFILE_MEDIATES(profile, AA_CLASS_NET);
 229        __be16 be_af = cpu_to_be16(AF);
 230
 231        if (!state)
 232                return 0;
 233        return aa_dfa_match_len(profile->policy.dfa, state, (char *) &be_af, 2);
 234}
 235
 236/**
 237 * aa_get_profile - increment refcount on profile @p
 238 * @p: profile  (MAYBE NULL)
 239 *
 240 * Returns: pointer to @p if @p is NULL will return NULL
 241 * Requires: @p must be held with valid refcount when called
 242 */
 243static inline struct aa_profile *aa_get_profile(struct aa_profile *p)
 244{
 245        if (p)
 246                kref_get(&(p->label.count));
 247
 248        return p;
 249}
 250
 251/**
 252 * aa_get_profile_not0 - increment refcount on profile @p found via lookup
 253 * @p: profile  (MAYBE NULL)
 254 *
 255 * Returns: pointer to @p if @p is NULL will return NULL
 256 * Requires: @p must be held with valid refcount when called
 257 */
 258static inline struct aa_profile *aa_get_profile_not0(struct aa_profile *p)
 259{
 260        if (p && kref_get_unless_zero(&p->label.count))
 261                return p;
 262
 263        return NULL;
 264}
 265
 266/**
 267 * aa_get_profile_rcu - increment a refcount profile that can be replaced
 268 * @p: pointer to profile that can be replaced (NOT NULL)
 269 *
 270 * Returns: pointer to a refcounted profile.
 271 *     else NULL if no profile
 272 */
 273static inline struct aa_profile *aa_get_profile_rcu(struct aa_profile __rcu **p)
 274{
 275        struct aa_profile *c;
 276
 277        rcu_read_lock();
 278        do {
 279                c = rcu_dereference(*p);
 280        } while (c && !kref_get_unless_zero(&c->label.count));
 281        rcu_read_unlock();
 282
 283        return c;
 284}
 285
 286/**
 287 * aa_put_profile - decrement refcount on profile @p
 288 * @p: profile  (MAYBE NULL)
 289 */
 290static inline void aa_put_profile(struct aa_profile *p)
 291{
 292        if (p)
 293                kref_put(&p->label.count, aa_label_kref);
 294}
 295
 296static inline int AUDIT_MODE(struct aa_profile *profile)
 297{
 298        if (aa_g_audit != AUDIT_NORMAL)
 299                return aa_g_audit;
 300
 301        return profile->audit;
 302}
 303
 304bool policy_view_capable(struct aa_ns *ns);
 305bool policy_admin_capable(struct aa_ns *ns);
 306int aa_may_manage_policy(struct aa_label *label, struct aa_ns *ns,
 307                         u32 mask);
 308
 309#endif /* __AA_POLICY_H */
 310