policy.h 11.2 KB
Newer Older
J
John Johansen 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
/*
 * AppArmor security module
 *
 * This file contains AppArmor policy definitions.
 *
 * Copyright (C) 1998-2008 Novell/SUSE
 * Copyright 2009-2010 Canonical Ltd.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, version 2 of the
 * License.
 */

#ifndef __AA_POLICY_H
#define __AA_POLICY_H

#include <linux/capability.h>
#include <linux/cred.h>
#include <linux/kref.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/socket.h>

#include "apparmor.h"
#include "audit.h"
#include "capability.h"
#include "domain.h"
#include "file.h"
#include "resource.h"

32
extern const char *const profile_mode_names[];
J
John Johansen 已提交
33 34
#define APPARMOR_NAMES_MAX_INDEX 3

35 36 37
#define PROFILE_MODE(_profile, _mode)		\
	((aa_g_profile_mode == (_mode)) ||	\
	 ((_profile)->mode == (_mode)))
J
John Johansen 已提交
38

39 40 41
#define COMPLAIN_MODE(_profile)	PROFILE_MODE((_profile), APPARMOR_COMPLAIN)

#define KILL_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_KILL)
J
John Johansen 已提交
42 43 44

#define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT)

45 46
#define PROFILE_INVALID(_profile) ((_profile)->flags & PFLAG_INVALID)

47 48
#define on_list_rcu(X) (!list_empty(X) && (X)->prev != LIST_POISON2)

J
John Johansen 已提交
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
/*
 * FIXME: currently need a clean way to replace and remove profiles as a
 * set.  It should be done at the namespace level.
 * Either, with a set of profiles loaded at the namespace level or via
 * a mark and remove marked interface.
 */
enum profile_mode {
	APPARMOR_ENFORCE,	/* enforce access rules */
	APPARMOR_COMPLAIN,	/* allow and log access violations */
	APPARMOR_KILL,		/* kill task on access violation */
};

enum profile_flags {
	PFLAG_HAT = 1,			/* profile is a hat */
	PFLAG_UNCONFINED = 2,		/* profile is an unconfined profile */
	PFLAG_NULL = 4,			/* profile is null learning profile */
	PFLAG_IX_ON_NAME_ERROR = 8,	/* fallback to ix on name lookup fail */
	PFLAG_IMMUTABLE = 0x10,		/* don't allow changes/replacement */
	PFLAG_USER_DEFINED = 0x20,	/* user based profile - lower privs */
	PFLAG_NO_LIST_REF = 0x40,	/* list doesn't keep profile ref */
	PFLAG_OLD_NULL_TRANS = 0x100,	/* use // as the null transition */
70
	PFLAG_INVALID = 0x200,		/* profile replaced/removed */
71
	PFLAG_NS_COUNT = 0x400,		/* carries NS ref count */
J
John Johansen 已提交
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111

	/* These flags must correspond with PATH_flags */
	PFLAG_MEDIATE_DELETED = 0x10000, /* mediate instead delegate deleted */
};

struct aa_profile;

/* struct aa_policy - common part of both namespaces and profiles
 * @name: name of the object
 * @hname - The hierarchical name
 * @list: list policy object is on
 * @profiles: head of the profiles list contained in the object
 */
struct aa_policy {
	char *name;
	char *hname;
	struct list_head list;
	struct list_head profiles;
};

/* struct aa_ns_acct - accounting of profiles in namespace
 * @max_size: maximum space allowed for all profiles in namespace
 * @max_count: maximum number of profiles that can be in this namespace
 * @size: current size of profiles
 * @count: current count of profiles (includes null profiles)
 */
struct aa_ns_acct {
	int max_size;
	int max_count;
	int size;
	int count;
};

/* struct aa_namespace - namespace for a set of profiles
 * @base: common policy
 * @parent: parent of namespace
 * @lock: lock for modifying the object
 * @acct: accounting for the namespace
 * @unconfined: special unconfined profile for the namespace
 * @sub_ns: list of namespaces under the current namespace.
112
 * @uniq_null: uniq value used for null learning profiles
J
John Johansen 已提交
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
 *
 * An aa_namespace defines the set profiles that are searched to determine
 * which profile to attach to a task.  Profiles can not be shared between
 * aa_namespaces and profile names within a namespace are guaranteed to be
 * unique.  When profiles in separate namespaces have the same name they
 * are NOT considered to be equivalent.
 *
 * Namespaces are hierarchical and only namespaces and profiles below the
 * current namespace are visible.
 *
 * Namespace names must be unique and can not contain the characters :/\0
 *
 * FIXME TODO: add vserver support of namespaces (can it all be done in
 *             userspace?)
 */
struct aa_namespace {
	struct aa_policy base;
	struct aa_namespace *parent;
131
	struct mutex lock;
J
John Johansen 已提交
132 133 134
	struct aa_ns_acct acct;
	struct aa_profile *unconfined;
	struct list_head sub_ns;
135
	atomic_t uniq_null;
J
John Johansen 已提交
136 137
};

138 139 140 141 142 143 144 145 146 147 148
/* struct aa_policydb - match engine for a policy
 * dfa: dfa pattern match
 * start: set of start states for the different classes of data
 */
struct aa_policydb {
	/* Generic policy DFA specific rule types will be subsections of it */
	struct aa_dfa *dfa;
	unsigned int start[AA_CLASS_LAST + 1];

};

149 150 151 152 153 154
struct aa_replacedby {
	struct kref count;
	struct aa_profile __rcu *profile;
};


J
John Johansen 已提交
155 156
/* struct aa_profile - basic confinement data
 * @base - base components of the profile (name, refcount, lists, lock ...)
157
 * @count: reference count of the obj
158
 * @rcu: rcu head used when removing from @list
J
John Johansen 已提交
159 160 161 162 163 164 165 166 167 168 169
 * @parent: parent of profile
 * @ns: namespace the profile is in
 * @replacedby: is set to the profile that replaced this profile
 * @rename: optional profile name that this profile renamed
 * @xmatch: optional extended matching for unconfined executables names
 * @xmatch_len: xmatch prefix len, used to determine xmatch priority
 * @audit: the auditing mode of the profile
 * @mode: the enforcement mode of the profile
 * @flags: flags controlling profile behavior
 * @path_flags: flags controlling path generation behavior
 * @size: the memory consumed by this profiles rules
170
 * @policy: general match rules governing policy
J
John Johansen 已提交
171 172 173 174 175 176 177 178 179
 * @file: The set of rules governing basic file access and domain transitions
 * @caps: capabilities for the profile
 * @rlimits: rlimits for the profile
 *
 * The AppArmor profile contains the basic confinement data.  Each profile
 * has a name, and exists in a namespace.  The @name and @exec_match are
 * used to determine profile attachment against unconfined tasks.  All other
 * attachments are determined by profile X transition rules.
 *
180
 * The @replacedby struct is write protected by the profile lock.
J
John Johansen 已提交
181 182 183 184 185 186 187 188 189 190
 *
 * Profiles have a hierarchy where hats and children profiles keep
 * a reference to their parent.
 *
 * Profile names can not begin with a : and can not contain the \0
 * character.  If a profile name begins with / it will be considered when
 * determining profile attachment on "unconfined" tasks.
 */
struct aa_profile {
	struct aa_policy base;
191
	struct kref count;
192
	struct rcu_head rcu;
193
	struct aa_profile __rcu *parent;
J
John Johansen 已提交
194 195

	struct aa_namespace *ns;
196
	struct aa_replacedby *replacedby;
J
John Johansen 已提交
197 198 199 200 201 202
	const char *rename;

	struct aa_dfa *xmatch;
	int xmatch_len;
	enum audit_mode audit;
	enum profile_mode mode;
203
	long flags;
J
John Johansen 已提交
204 205 206
	u32 path_flags;
	int size;

207
	struct aa_policydb policy;
J
John Johansen 已提交
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
	struct aa_file_rules file;
	struct aa_caps caps;
	struct aa_rlimit rlimits;
};

extern struct aa_namespace *root_ns;
extern enum profile_mode aa_g_profile_mode;

void aa_add_profile(struct aa_policy *common, struct aa_profile *profile);

bool aa_ns_visible(struct aa_namespace *curr, struct aa_namespace *view);
const char *aa_ns_name(struct aa_namespace *parent, struct aa_namespace *child);
int aa_alloc_root_ns(void);
void aa_free_root_ns(void);
void aa_free_namespace_kref(struct kref *kref);

struct aa_namespace *aa_find_namespace(struct aa_namespace *root,
				       const char *name);


228
void aa_free_replacedby_kref(struct kref *kref);
J
John Johansen 已提交
229 230
struct aa_profile *aa_alloc_profile(const char *name);
struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat);
231
void aa_free_profile(struct aa_profile *profile);
J
John Johansen 已提交
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
void aa_free_profile_kref(struct kref *kref);
struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name);
struct aa_profile *aa_lookup_profile(struct aa_namespace *ns, const char *name);
struct aa_profile *aa_match_profile(struct aa_namespace *ns, const char *name);

ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace);
ssize_t aa_remove_profiles(char *name, size_t size);

#define PROF_ADD 1
#define PROF_REPLACE 0

#define unconfined(X) ((X)->flags & PFLAG_UNCONFINED)


/**
 * aa_get_profile - increment refcount on profile @p
 * @p: profile  (MAYBE NULL)
 *
 * Returns: pointer to @p if @p is NULL will return NULL
 * Requires: @p must be held with valid refcount when called
 */
static inline struct aa_profile *aa_get_profile(struct aa_profile *p)
{
	if (p)
256
		kref_get(&(p->count));
J
John Johansen 已提交
257 258 259 260

	return p;
}

261 262 263 264 265 266 267 268 269
/**
 * aa_get_profile_not0 - increment refcount on profile @p found via lookup
 * @p: profile  (MAYBE NULL)
 *
 * Returns: pointer to @p if @p is NULL will return NULL
 * Requires: @p must be held with valid refcount when called
 */
static inline struct aa_profile *aa_get_profile_not0(struct aa_profile *p)
{
270
	if (p && kref_get_not0(&p->count))
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
		return p;

	return NULL;
}

/**
 * aa_get_profile_rcu - increment a refcount profile that can be replaced
 * @p: pointer to profile that can be replaced (NOT NULL)
 *
 * Returns: pointer to a refcounted profile.
 *     else NULL if no profile
 */
static inline struct aa_profile *aa_get_profile_rcu(struct aa_profile __rcu **p)
{
	struct aa_profile *c;

	rcu_read_lock();
	do {
		c = rcu_dereference(*p);
290
	} while (c && !kref_get_not0(&c->count));
291 292 293 294 295
	rcu_read_unlock();

	return c;
}

296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
/**
 * aa_get_newest_profile - find the newest version of @profile
 * @profile: the profile to check for newer versions of
 *
 * Returns: refcounted newest version of @profile taking into account
 *          replacement, renames and removals
 *          return @profile.
 */
static inline struct aa_profile *aa_get_newest_profile(struct aa_profile *p)
{
	if (!p)
		return NULL;

	if (PROFILE_INVALID(p))
		return aa_get_profile_rcu(&p->replacedby->profile);

	return aa_get_profile(p);
}

J
John Johansen 已提交
315 316 317 318 319 320
/**
 * aa_put_profile - decrement refcount on profile @p
 * @p: profile  (MAYBE NULL)
 */
static inline void aa_put_profile(struct aa_profile *p)
{
321 322
	if (p)
		kref_put(&p->count, aa_free_profile_kref);
J
John Johansen 已提交
323 324
}

325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
static inline struct aa_replacedby *aa_get_replacedby(struct aa_replacedby *p)
{
	if (p)
		kref_get(&(p->count));

	return p;
}

static inline void aa_put_replacedby(struct aa_replacedby *p)
{
	if (p)
		kref_put(&p->count, aa_free_replacedby_kref);
}

/* requires profile list write lock held */
static inline void __aa_update_replacedby(struct aa_profile *orig,
					  struct aa_profile *new)
{
	struct aa_profile *tmp = rcu_dereference(orig->replacedby->profile);
	rcu_assign_pointer(orig->replacedby->profile, aa_get_profile(new));
	orig->flags |= PFLAG_INVALID;
	aa_put_profile(tmp);
}

349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
/**
 * aa_get_namespace - increment references count on @ns
 * @ns: namespace to increment reference count of (MAYBE NULL)
 *
 * Returns: pointer to @ns, if @ns is NULL returns NULL
 * Requires: @ns must be held with valid refcount when called
 */
static inline struct aa_namespace *aa_get_namespace(struct aa_namespace *ns)
{
	if (ns)
		aa_get_profile(ns->unconfined);

	return ns;
}

/**
 * aa_put_namespace - decrement refcount on @ns
 * @ns: namespace to put reference of
 *
 * Decrement reference count of @ns and if no longer in use free it
 */
static inline void aa_put_namespace(struct aa_namespace *ns)
{
	if (ns)
		aa_put_profile(ns->unconfined);
}

J
John Johansen 已提交
376 377 378 379 380 381 382 383 384 385 386
static inline int AUDIT_MODE(struct aa_profile *profile)
{
	if (aa_g_audit != AUDIT_NORMAL)
		return aa_g_audit;

	return profile->audit;
}

bool aa_may_manage_policy(int op);

#endif /* __AA_POLICY_H */