2019-06-01 10:08:55 +02:00
/* SPDX-License-Identifier: GPL-2.0-only */
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 .
*/
# ifndef __AA_POLICY_H
# define __AA_POLICY_H
# include <linux/capability.h>
# include <linux/cred.h>
# include <linux/kref.h>
2017-01-15 16:49:28 -08:00
# include <linux/rhashtable.h>
2010-07-29 14:48:00 -07:00
# 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"
2017-06-09 08:14:28 -07:00
# include "label.h"
2017-07-18 23:18:33 -07:00
# include "net.h"
2017-05-26 01:57:09 -07:00
# include "perms.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
2017-01-16 00:42:50 -08:00
extern int unprivileged_userns_apparmor_policy ;
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
2017-06-09 08:14:28 -07:00
# define PROFILE_IS_HAT(_profile) ((_profile)->label.flags & FLAG_HAT)
2010-07-29 14:48:00 -07:00
2017-06-09 08:14:28 -07:00
# define profile_is_stale(_profile) (label_is_stale(&(_profile)->label))
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
} ;
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-15 16:49:28 -08:00
/* struct aa_data - generic data structure
* key : name for retrieving this data
* size : size of data in bytes
* data : binary data
* head : reserved for rhashtable
*/
struct aa_data {
char * key ;
u32 size ;
char * data ;
struct rhash_head head ;
} ;
2013-07-10 21:07:43 -07:00
2010-07-29 14:48:00 -07:00
/* struct aa_profile - basic confinement data
* @ base - base components of the profile ( name , refcount , lists , lock . . . )
2017-06-09 08:14:28 -07:00
* @ label - label this profile is an extension of
2010-07-29 14:48:00 -07:00
* @ parent : parent of profile
* @ ns : namespace the profile is in
* @ 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
* @ path_flags : flags controlling path generation behavior
2017-05-22 03:06:52 -07:00
* @ disconnected : what to prepend if attach_disconnected is specified
2010-07-29 14:48:00 -07:00
* @ 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
2017-01-15 16:49:28 -08:00
* @ data : hashtable for free - form policy aa_data
2013-07-10 21:13:43 -07:00
*
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 .
*
* 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: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 ;
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 ;
2010-07-29 14:48:00 -07:00
u32 path_flags ;
2017-05-22 03:06:52 -07:00
const char * disconnected ;
2010-07-29 14:48:00 -07:00
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 ;
2018-02-08 12:37:19 -08:00
int xattr_count ;
char * * xattrs ;
2010-07-29 14:48:00 -07:00
struct aa_rlimit rlimits ;
2013-07-10 21:13:43 -07:00
2018-05-24 13:27:46 -07:00
int secmark_count ;
struct aa_secmark * secmark ;
2017-01-16 00:42:55 -08:00
struct aa_loaddata * rawdata ;
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 ] ;
2017-01-15 16:49:28 -08:00
struct rhashtable * data ;
2017-06-09 08:14:28 -07:00
struct aa_label label ;
2010-07-29 14:48:00 -07:00
} ;
extern enum profile_mode aa_g_profile_mode ;
2017-05-26 01:45:08 -07:00
# define AA_MAY_LOAD_POLICY AA_MAY_APPEND
# define AA_MAY_REPLACE_POLICY AA_MAY_WRITE
# define AA_MAY_REMOVE_POLICY AA_MAY_DELETE
2017-06-09 08:14:28 -07:00
# define profiles_ns(P) ((P)->ns)
# define name_is_shared(A, B) ((A)->hname && (A)->hname == (B)->hname)
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-06-09 08:14:28 -07:00
struct aa_profile * aa_alloc_profile ( const char * name , struct aa_proxy * proxy ,
gfp_t gfp ) ;
2017-01-16 00:42:36 -08:00
struct aa_profile * aa_new_null_profile ( struct aa_profile * parent , bool hat ,
const char * base , gfp_t gfp ) ;
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-06-09 08:14:28 -07:00
struct aa_profile * aa_fqlookupn_profile ( struct aa_label * base ,
2017-01-16 00:42:24 -08:00
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-06-09 08:14:28 -07:00
ssize_t aa_replace_profiles ( struct aa_ns * view , struct aa_label * label ,
2017-05-26 01:45:08 -07:00
u32 mask , struct aa_loaddata * udata ) ;
2017-06-09 08:14:28 -07:00
ssize_t aa_remove_profiles ( struct aa_ns * view , struct aa_label * label ,
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
2017-06-09 08:14:28 -07:00
# define profile_unconfined(X) ((X)->mode == APPARMOR_UNCONFINED)
/**
* aa_get_newest_profile - simple wrapper fn to wrap the label version
* @ p : profile ( NOT NULL )
*
* Returns refcount to newest version of the profile ( maybe @ p )
*
* Requires : @ p must be held with a valid refcount
*/
static inline struct aa_profile * aa_get_newest_profile ( struct aa_profile * p )
{
return labels_profile ( aa_get_newest_label ( & p - > label ) ) ;
}
2010-07-29 14:48:00 -07:00
2019-05-26 06:42:23 -07:00
static inline unsigned int PROFILE_MEDIATES ( struct aa_profile * profile ,
unsigned char class )
{
if ( class < = AA_CLASS_LAST )
return profile - > policy . start [ class ] ;
else
return aa_dfa_match_len ( profile - > policy . dfa ,
profile - > policy . start [ 0 ] , & class , 1 ) ;
}
2017-07-18 23:18:33 -07:00
static inline unsigned int PROFILE_MEDIATES_AF ( struct aa_profile * profile ,
u16 AF ) {
unsigned int state = PROFILE_MEDIATES ( profile , AA_CLASS_NET ) ;
__be16 be_af = cpu_to_be16 ( AF ) ;
if ( ! state )
return 0 ;
return aa_dfa_match_len ( profile - > policy . dfa , state , ( char * ) & be_af , 2 ) ;
}
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 )
2017-06-09 08:14:28 -07:00
kref_get ( & ( p - > label . 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 )
{
2017-06-09 08:14:28 -07:00
if ( p & & kref_get_unless_zero ( & p - > label . 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 ) ;
2017-06-09 08:14:28 -07:00
} while ( c & & ! kref_get_unless_zero ( & c - > label . count ) ) ;
2013-07-10 21:06:43 -07:00
rcu_read_unlock ( ) ;
return c ;
}
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 )
2017-06-09 08:14:28 -07:00
kref_put ( & p - > label . count , aa_label_kref ) ;
2013-07-10 21:08: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 ;
}
2020-06-30 17:00:11 -07:00
bool aa_policy_view_capable ( struct aa_label * label , struct aa_ns * ns ) ;
bool aa_policy_admin_capable ( struct aa_label * label , struct aa_ns * ns ) ;
2017-06-09 08:14:28 -07:00
int aa_may_manage_policy ( struct aa_label * label , struct aa_ns * ns ,
2017-05-26 01:45:08 -07:00
u32 mask ) ;
2020-06-30 17:00:11 -07:00
bool aa_current_policy_view_capable ( struct aa_ns * ns ) ;
bool aa_current_policy_admin_capable ( struct aa_ns * ns ) ;
2010-07-29 14:48:00 -07:00
# endif /* __AA_POLICY_H */