2010-07-29 14:48:00 -07:00
/*
* 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"
2017-01-16 00:42:13 -08:00
# include "lib.h"
2010-07-29 14:48:00 -07:00
# include "resource.h"
2017-01-16 00:42:15 -08:00
2017-01-16 00:42:16 -08:00
struct aa_ns ;
2017-01-16 00:42:15 -08:00
2013-07-10 21:13:43 -07:00
extern const char * const aa_profile_mode_names [ ] ;
# define APPARMOR_MODE_NAMES_MAX_INDEX 4
2010-07-29 14:48:00 -07:00
2013-02-18 16:01:34 -08:00
# define PROFILE_MODE(_profile, _mode) \
( ( aa_g_profile_mode = = ( _mode ) ) | | \
( ( _profile ) - > mode = = ( _mode ) ) )
2010-07-29 14:48:00 -07:00
2013-02-18 16:01:34 -08:00
# define COMPLAIN_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_COMPLAIN)
# define KILL_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_KILL)
2010-07-29 14:48:00 -07:00
# define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT)
2017-01-16 00:42:18 -08:00
# define profile_is_stale(_profile) ((_profile)->flags & PFLAG_STALE)
2013-07-10 21:07:43 -07:00
2013-07-10 21:06:43 -07:00
# define on_list_rcu(X) (!list_empty(X) && (X)->prev != LIST_POISON2)
2010-07-29 14:48:00 -07:00
/*
* 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 */
2013-07-10 21:12:43 -07:00
APPARMOR_UNCONFINED , /* profile set to unconfined */
2010-07-29 14:48:00 -07:00
} ;
enum profile_flags {
PFLAG_HAT = 1 , /* profile is a hat */
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 */
2017-01-16 00:42:18 -08:00
PFLAG_STALE = 0x200 , /* profile replaced/removed */
2013-07-10 21:08:43 -07:00
PFLAG_NS_COUNT = 0x400 , /* carries NS ref count */
2010-07-29 14:48:00 -07:00
/* These flags must correspond with PATH_flags */
PFLAG_MEDIATE_DELETED = 0x10000 , /* mediate instead delegate deleted */
} ;
struct aa_profile ;
2012-02-16 07:07:53 -08:00
/* 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 ] ;
} ;
2017-01-16 00:42:19 -08:00
struct aa_proxy {
2013-07-10 21:07:43 -07:00
struct kref count ;
struct aa_profile __rcu * profile ;
} ;
2010-07-29 14:48:00 -07:00
/* struct aa_profile - basic confinement data
* @ base - base components of the profile ( name , refcount , lists , lock . . . )
2013-07-10 21:08:43 -07:00
* @ count : reference count of the obj
2013-07-10 21:10:43 -07:00
* @ rcu : rcu head used when removing from @ list
2010-07-29 14:48:00 -07:00
* @ parent : parent of profile
* @ ns : namespace the profile is in
2017-01-16 00:42:19 -08:00
* @ proxy : is set to the profile that replaced this profile
2010-07-29 14:48:00 -07:00
* @ rename : optional profile name that this profile renamed
2013-07-10 21:17:43 -07:00
* @ attach : human readable attachment string
2010-07-29 14:48:00 -07:00
* @ 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
2012-02-16 07:07:53 -08:00
* @ policy : general match rules governing policy
2010-07-29 14:48:00 -07:00
* @ file : The set of rules governing basic file access and domain transitions
* @ caps : capabilities for the profile
* @ rlimits : rlimits for the profile
*
2013-07-10 21:13:43 -07:00
* @ dents : dentries for the profiles file entries in apparmorfs
* @ dirname : name of the profile dir in apparmorfs
*
2010-07-29 14:48:00 -07:00
* 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 .
*
2017-01-16 00:42:19 -08:00
* The @ proxy struct is write protected by the profile lock .
2010-07-29 14:48:00 -07:00
*
* 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 ;
2013-07-10 21:08:43 -07:00
struct kref count ;
2013-07-10 21:10:43 -07:00
struct rcu_head rcu ;
2013-07-10 21:06:43 -07:00
struct aa_profile __rcu * parent ;
2010-07-29 14:48:00 -07:00
2017-01-16 00:42:16 -08:00
struct aa_ns * ns ;
2017-01-16 00:42:19 -08:00
struct aa_proxy * proxy ;
2010-07-29 14:48:00 -07:00
const char * rename ;
2013-07-10 21:17:43 -07:00
const char * attach ;
2010-07-29 14:48:00 -07:00
struct aa_dfa * xmatch ;
int xmatch_len ;
enum audit_mode audit ;
2013-07-10 21:12:43 -07:00
long mode ;
2013-07-10 21:07:43 -07:00
long flags ;
2010-07-29 14:48:00 -07:00
u32 path_flags ;
int size ;
2012-02-16 07:07:53 -08:00
struct aa_policydb policy ;
2010-07-29 14:48:00 -07:00
struct aa_file_rules file ;
struct aa_caps caps ;
struct aa_rlimit rlimits ;
2013-07-10 21:13:43 -07:00
2013-08-14 11:27:36 -07:00
unsigned char * hash ;
2013-07-10 21:13:43 -07:00
char * dirname ;
struct dentry * dents [ AAFS_PROF_SIZEOF ] ;
2010-07-29 14:48:00 -07:00
} ;
extern enum profile_mode aa_g_profile_mode ;
2017-01-16 00:42:19 -08:00
void __aa_update_proxy ( struct aa_profile * orig , struct aa_profile * new ) ;
2010-07-29 14:48:00 -07:00
2017-01-16 00:42:15 -08:00
void aa_add_profile ( struct aa_policy * common , struct aa_profile * profile ) ;
2010-07-29 14:48:00 -07:00
2017-01-16 00:42:19 -08:00
void aa_free_proxy_kref ( struct kref * kref ) ;
2017-01-16 00:42:35 -08:00
struct aa_profile * aa_alloc_profile ( const char * name , gfp_t gfp ) ;
2010-07-29 14:48:00 -07:00
struct aa_profile * aa_new_null_profile ( struct aa_profile * parent , int hat ) ;
2013-07-10 21:11:43 -07:00
void aa_free_profile ( struct aa_profile * profile ) ;
2010-07-29 14:48:00 -07:00
void aa_free_profile_kref ( struct kref * kref ) ;
struct aa_profile * aa_find_child ( struct aa_profile * parent , const char * name ) ;
2017-01-16 00:42:21 -08:00
struct aa_profile * aa_lookupn_profile ( struct aa_ns * ns , const char * hname ,
size_t n ) ;
2017-01-16 00:42:16 -08:00
struct aa_profile * aa_lookup_profile ( struct aa_ns * ns , const char * name ) ;
2017-01-16 00:42:24 -08:00
struct aa_profile * aa_fqlookupn_profile ( struct aa_profile * base ,
const char * fqname , size_t n ) ;
2017-01-16 00:42:16 -08:00
struct aa_profile * aa_match_profile ( struct aa_ns * ns , const char * name ) ;
2010-07-29 14:48:00 -07:00
2017-01-16 00:42:34 -08:00
ssize_t aa_replace_profiles ( struct aa_ns * view , void * udata , size_t size ,
bool noreplace ) ;
2010-07-29 14:48:00 -07:00
ssize_t aa_remove_profiles ( char * name , size_t size ) ;
2017-01-16 00:42:15 -08:00
void __aa_profile_list_release ( struct list_head * head ) ;
2010-07-29 14:48:00 -07:00
# define PROF_ADD 1
# define PROF_REPLACE 0
2013-07-10 21:12:43 -07:00
# define unconfined(X) ((X)->mode == APPARMOR_UNCONFINED)
2010-07-29 14:48:00 -07:00
/**
* 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 )
2013-07-10 21:08:43 -07:00
kref_get ( & ( p - > count ) ) ;
2010-07-29 14:48:00 -07:00
return p ;
}
2013-07-10 21:06:43 -07:00
/**
* 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 )
{
2013-07-10 21:08:43 -07:00
if ( p & & kref_get_not0 ( & p - > count ) )
2013-07-10 21:06:43 -07:00
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 ) ;
2013-07-10 21:08:43 -07:00
} while ( c & & ! kref_get_not0 ( & c - > count ) ) ;
2013-07-10 21:06:43 -07:00
rcu_read_unlock ( ) ;
return c ;
}
2013-07-10 21:07:43 -07:00
/**
* 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 ;
2017-01-16 00:42:18 -08:00
if ( profile_is_stale ( p ) )
2017-01-16 00:42:19 -08:00
return aa_get_profile_rcu ( & p - > proxy - > profile ) ;
2013-07-10 21:07:43 -07:00
return aa_get_profile ( p ) ;
}
2010-07-29 14:48:00 -07:00
/**
* aa_put_profile - decrement refcount on profile @ p
* @ p : profile ( MAYBE NULL )
*/
static inline void aa_put_profile ( struct aa_profile * p )
{
2013-07-10 21:10:43 -07:00
if ( p )
kref_put ( & p - > count , aa_free_profile_kref ) ;
2010-07-29 14:48:00 -07:00
}
2017-01-16 00:42:19 -08:00
static inline struct aa_proxy * aa_get_proxy ( struct aa_proxy * p )
2013-07-10 21:07:43 -07:00
{
if ( p )
kref_get ( & ( p - > count ) ) ;
return p ;
}
2017-01-16 00:42:19 -08:00
static inline void aa_put_proxy ( struct aa_proxy * p )
2013-07-10 21:07:43 -07:00
{
if ( p )
2017-01-16 00:42:19 -08:00
kref_put ( & p - > count , aa_free_proxy_kref ) ;
2013-07-10 21:07:43 -07:00
}
2010-07-29 14:48:00 -07:00
static inline int AUDIT_MODE ( struct aa_profile * profile )
{
if ( aa_g_audit ! = AUDIT_NORMAL )
return aa_g_audit ;
return profile - > audit ;
}
2016-06-22 18:01:08 -07:00
bool policy_view_capable ( void ) ;
bool policy_admin_capable ( void ) ;
2010-07-29 14:48:00 -07:00
bool aa_may_manage_policy ( int op ) ;
# endif /* __AA_POLICY_H */