LCOV - code coverage report
Current view: top level - security/apparmor/include - policy.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 6 22 27.3 %
Date: 2014-02-18 Functions: 0 0 -
Branches: 20 287 7.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * AppArmor security module
       3                 :            :  *
       4                 :            :  * This file contains AppArmor policy definitions.
       5                 :            :  *
       6                 :            :  * Copyright (C) 1998-2008 Novell/SUSE
       7                 :            :  * Copyright 2009-2010 Canonical Ltd.
       8                 :            :  *
       9                 :            :  * This program is free software; you can redistribute it and/or
      10                 :            :  * modify it under the terms of the GNU General Public License as
      11                 :            :  * published by the Free Software Foundation, version 2 of the
      12                 :            :  * License.
      13                 :            :  */
      14                 :            : 
      15                 :            : #ifndef __AA_POLICY_H
      16                 :            : #define __AA_POLICY_H
      17                 :            : 
      18                 :            : #include <linux/capability.h>
      19                 :            : #include <linux/cred.h>
      20                 :            : #include <linux/kref.h>
      21                 :            : #include <linux/sched.h>
      22                 :            : #include <linux/slab.h>
      23                 :            : #include <linux/socket.h>
      24                 :            : 
      25                 :            : #include "apparmor.h"
      26                 :            : #include "audit.h"
      27                 :            : #include "capability.h"
      28                 :            : #include "domain.h"
      29                 :            : #include "file.h"
      30                 :            : #include "resource.h"
      31                 :            : 
      32                 :            : extern const char *const aa_profile_mode_names[];
      33                 :            : #define APPARMOR_MODE_NAMES_MAX_INDEX 4
      34                 :            : 
      35                 :            : #define PROFILE_MODE(_profile, _mode)           \
      36                 :            :         ((aa_g_profile_mode == (_mode)) ||      \
      37                 :            :          ((_profile)->mode == (_mode)))
      38                 :            : 
      39                 :            : #define COMPLAIN_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_COMPLAIN)
      40                 :            : 
      41                 :            : #define KILL_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_KILL)
      42                 :            : 
      43                 :            : #define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT)
      44                 :            : 
      45                 :            : #define PROFILE_INVALID(_profile) ((_profile)->flags & PFLAG_INVALID)
      46                 :            : 
      47                 :            : #define on_list_rcu(X) (!list_empty(X) && (X)->prev != LIST_POISON2)
      48                 :            : 
      49                 :            : /*
      50                 :            :  * FIXME: currently need a clean way to replace and remove profiles as a
      51                 :            :  * set.  It should be done at the namespace level.
      52                 :            :  * Either, with a set of profiles loaded at the namespace level or via
      53                 :            :  * a mark and remove marked interface.
      54                 :            :  */
      55                 :            : enum profile_mode {
      56                 :            :         APPARMOR_ENFORCE,       /* enforce access rules */
      57                 :            :         APPARMOR_COMPLAIN,      /* allow and log access violations */
      58                 :            :         APPARMOR_KILL,          /* kill task on access violation */
      59                 :            :         APPARMOR_UNCONFINED,    /* profile set to unconfined */
      60                 :            : };
      61                 :            : 
      62                 :            : enum profile_flags {
      63                 :            :         PFLAG_HAT = 1,                  /* profile is a hat */
      64                 :            :         PFLAG_NULL = 4,                 /* profile is null learning profile */
      65                 :            :         PFLAG_IX_ON_NAME_ERROR = 8,     /* fallback to ix on name lookup fail */
      66                 :            :         PFLAG_IMMUTABLE = 0x10,         /* don't allow changes/replacement */
      67                 :            :         PFLAG_USER_DEFINED = 0x20,      /* user based profile - lower privs */
      68                 :            :         PFLAG_NO_LIST_REF = 0x40,       /* list doesn't keep profile ref */
      69                 :            :         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 */
      72                 :            : 
      73                 :            :         /* These flags must correspond with PATH_flags */
      74                 :            :         PFLAG_MEDIATE_DELETED = 0x10000, /* mediate instead delegate deleted */
      75                 :            : };
      76                 :            : 
      77                 :            : struct aa_profile;
      78                 :            : 
      79                 :            : /* struct aa_policy - common part of both namespaces and profiles
      80                 :            :  * @name: name of the object
      81                 :            :  * @hname - The hierarchical name
      82                 :            :  * @list: list policy object is on
      83                 :            :  * @profiles: head of the profiles list contained in the object
      84                 :            :  */
      85                 :            : struct aa_policy {
      86                 :            :         char *name;
      87                 :            :         char *hname;
      88                 :            :         struct list_head list;
      89                 :            :         struct list_head profiles;
      90                 :            : };
      91                 :            : 
      92                 :            : /* struct aa_ns_acct - accounting of profiles in namespace
      93                 :            :  * @max_size: maximum space allowed for all profiles in namespace
      94                 :            :  * @max_count: maximum number of profiles that can be in this namespace
      95                 :            :  * @size: current size of profiles
      96                 :            :  * @count: current count of profiles (includes null profiles)
      97                 :            :  */
      98                 :            : struct aa_ns_acct {
      99                 :            :         int max_size;
     100                 :            :         int max_count;
     101                 :            :         int size;
     102                 :            :         int count;
     103                 :            : };
     104                 :            : 
     105                 :            : /* struct aa_namespace - namespace for a set of profiles
     106                 :            :  * @base: common policy
     107                 :            :  * @parent: parent of namespace
     108                 :            :  * @lock: lock for modifying the object
     109                 :            :  * @acct: accounting for the namespace
     110                 :            :  * @unconfined: special unconfined profile for the namespace
     111                 :            :  * @sub_ns: list of namespaces under the current namespace.
     112                 :            :  * @uniq_null: uniq value used for null learning profiles
     113                 :            :  * @uniq_id: a unique id count for the profiles in the namespace
     114                 :            :  * @dents: dentries for the namespaces file entries in apparmorfs
     115                 :            :  *
     116                 :            :  * An aa_namespace defines the set profiles that are searched to determine
     117                 :            :  * which profile to attach to a task.  Profiles can not be shared between
     118                 :            :  * aa_namespaces and profile names within a namespace are guaranteed to be
     119                 :            :  * unique.  When profiles in separate namespaces have the same name they
     120                 :            :  * are NOT considered to be equivalent.
     121                 :            :  *
     122                 :            :  * Namespaces are hierarchical and only namespaces and profiles below the
     123                 :            :  * current namespace are visible.
     124                 :            :  *
     125                 :            :  * Namespace names must be unique and can not contain the characters :/\0
     126                 :            :  *
     127                 :            :  * FIXME TODO: add vserver support of namespaces (can it all be done in
     128                 :            :  *             userspace?)
     129                 :            :  */
     130                 :            : struct aa_namespace {
     131                 :            :         struct aa_policy base;
     132                 :            :         struct aa_namespace *parent;
     133                 :            :         struct mutex lock;
     134                 :            :         struct aa_ns_acct acct;
     135                 :            :         struct aa_profile *unconfined;
     136                 :            :         struct list_head sub_ns;
     137                 :            :         atomic_t uniq_null;
     138                 :            :         long uniq_id;
     139                 :            : 
     140                 :            :         struct dentry *dents[AAFS_NS_SIZEOF];
     141                 :            : };
     142                 :            : 
     143                 :            : /* struct aa_policydb - match engine for a policy
     144                 :            :  * dfa: dfa pattern match
     145                 :            :  * start: set of start states for the different classes of data
     146                 :            :  */
     147                 :            : struct aa_policydb {
     148                 :            :         /* Generic policy DFA specific rule types will be subsections of it */
     149                 :            :         struct aa_dfa *dfa;
     150                 :            :         unsigned int start[AA_CLASS_LAST + 1];
     151                 :            : 
     152                 :            : };
     153                 :            : 
     154                 :            : struct aa_replacedby {
     155                 :            :         struct kref count;
     156                 :            :         struct aa_profile __rcu *profile;
     157                 :            : };
     158                 :            : 
     159                 :            : 
     160                 :            : /* struct aa_profile - basic confinement data
     161                 :            :  * @base - base components of the profile (name, refcount, lists, lock ...)
     162                 :            :  * @count: reference count of the obj
     163                 :            :  * @rcu: rcu head used when removing from @list
     164                 :            :  * @parent: parent of profile
     165                 :            :  * @ns: namespace the profile is in
     166                 :            :  * @replacedby: is set to the profile that replaced this profile
     167                 :            :  * @rename: optional profile name that this profile renamed
     168                 :            :  * @attach: human readable attachment string
     169                 :            :  * @xmatch: optional extended matching for unconfined executables names
     170                 :            :  * @xmatch_len: xmatch prefix len, used to determine xmatch priority
     171                 :            :  * @audit: the auditing mode of the profile
     172                 :            :  * @mode: the enforcement mode of the profile
     173                 :            :  * @flags: flags controlling profile behavior
     174                 :            :  * @path_flags: flags controlling path generation behavior
     175                 :            :  * @size: the memory consumed by this profiles rules
     176                 :            :  * @policy: general match rules governing policy
     177                 :            :  * @file: The set of rules governing basic file access and domain transitions
     178                 :            :  * @caps: capabilities for the profile
     179                 :            :  * @rlimits: rlimits for the profile
     180                 :            :  *
     181                 :            :  * @dents: dentries for the profiles file entries in apparmorfs
     182                 :            :  * @dirname: name of the profile dir in apparmorfs
     183                 :            :  *
     184                 :            :  * The AppArmor profile contains the basic confinement data.  Each profile
     185                 :            :  * has a name, and exists in a namespace.  The @name and @exec_match are
     186                 :            :  * used to determine profile attachment against unconfined tasks.  All other
     187                 :            :  * attachments are determined by profile X transition rules.
     188                 :            :  *
     189                 :            :  * The @replacedby struct is write protected by the profile lock.
     190                 :            :  *
     191                 :            :  * Profiles have a hierarchy where hats and children profiles keep
     192                 :            :  * a reference to their parent.
     193                 :            :  *
     194                 :            :  * Profile names can not begin with a : and can not contain the \0
     195                 :            :  * character.  If a profile name begins with / it will be considered when
     196                 :            :  * determining profile attachment on "unconfined" tasks.
     197                 :            :  */
     198                 :            : struct aa_profile {
     199                 :            :         struct aa_policy base;
     200                 :            :         struct kref count;
     201                 :            :         struct rcu_head rcu;
     202                 :            :         struct aa_profile __rcu *parent;
     203                 :            : 
     204                 :            :         struct aa_namespace *ns;
     205                 :            :         struct aa_replacedby *replacedby;
     206                 :            :         const char *rename;
     207                 :            : 
     208                 :            :         const char *attach;
     209                 :            :         struct aa_dfa *xmatch;
     210                 :            :         int xmatch_len;
     211                 :            :         enum audit_mode audit;
     212                 :            :         long mode;
     213                 :            :         long flags;
     214                 :            :         u32 path_flags;
     215                 :            :         int size;
     216                 :            : 
     217                 :            :         struct aa_policydb policy;
     218                 :            :         struct aa_file_rules file;
     219                 :            :         struct aa_caps caps;
     220                 :            :         struct aa_rlimit rlimits;
     221                 :            : 
     222                 :            :         unsigned char *hash;
     223                 :            :         char *dirname;
     224                 :            :         struct dentry *dents[AAFS_PROF_SIZEOF];
     225                 :            : };
     226                 :            : 
     227                 :            : extern struct aa_namespace *root_ns;
     228                 :            : extern enum profile_mode aa_g_profile_mode;
     229                 :            : 
     230                 :            : void aa_add_profile(struct aa_policy *common, struct aa_profile *profile);
     231                 :            : 
     232                 :            : bool aa_ns_visible(struct aa_namespace *curr, struct aa_namespace *view);
     233                 :            : const char *aa_ns_name(struct aa_namespace *parent, struct aa_namespace *child);
     234                 :            : int aa_alloc_root_ns(void);
     235                 :            : void aa_free_root_ns(void);
     236                 :            : void aa_free_namespace_kref(struct kref *kref);
     237                 :            : 
     238                 :            : struct aa_namespace *aa_find_namespace(struct aa_namespace *root,
     239                 :            :                                        const char *name);
     240                 :            : 
     241                 :            : 
     242                 :            : void aa_free_replacedby_kref(struct kref *kref);
     243                 :            : struct aa_profile *aa_alloc_profile(const char *name);
     244                 :            : struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat);
     245                 :            : void aa_free_profile(struct aa_profile *profile);
     246                 :            : void aa_free_profile_kref(struct kref *kref);
     247                 :            : struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name);
     248                 :            : struct aa_profile *aa_lookup_profile(struct aa_namespace *ns, const char *name);
     249                 :            : struct aa_profile *aa_match_profile(struct aa_namespace *ns, const char *name);
     250                 :            : 
     251                 :            : ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace);
     252                 :            : ssize_t aa_remove_profiles(char *name, size_t size);
     253                 :            : 
     254                 :            : #define PROF_ADD 1
     255                 :            : #define PROF_REPLACE 0
     256                 :            : 
     257                 :            : #define unconfined(X) ((X)->mode == APPARMOR_UNCONFINED)
     258                 :            : 
     259                 :            : 
     260                 :            : static inline struct aa_profile *aa_deref_parent(struct aa_profile *p)
     261                 :            : {
     262                 :            :         return rcu_dereference_protected(p->parent,
     263                 :            :                                          mutex_is_locked(&p->ns->lock));
     264                 :            : }
     265                 :            : 
     266                 :            : /**
     267                 :            :  * aa_get_profile - increment refcount on profile @p
     268                 :            :  * @p: profile  (MAYBE NULL)
     269                 :            :  *
     270                 :            :  * Returns: pointer to @p if @p is NULL will return NULL
     271                 :            :  * Requires: @p must be held with valid refcount when called
     272                 :            :  */
     273                 :            : static inline struct aa_profile *aa_get_profile(struct aa_profile *p)
     274                 :            : {
     275 [ #  # ][ #  # ]:    3688451 :         if (p)
         [ +  - ][ #  # ]
         [ +  - ][ +  + ]
         [ -  + ][ -  + ]
         [ #  # ][ #  # ]
            [ + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
           [ #  #  #  #  
             #  #  #  #  
              # ][ #  # ]
           [ #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
           [ #  #  #  #  
           #  # ][ #  #  
          #  #  #  #  #  
              # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     276                 :            :                 kref_get(&(p->count));
     277                 :            : 
     278                 :            :         return p;
     279                 :            : }
     280                 :            : 
     281                 :            : /**
     282                 :            :  * aa_get_profile_not0 - increment refcount on profile @p found via lookup
     283                 :            :  * @p: profile  (MAYBE NULL)
     284                 :            :  *
     285                 :            :  * Returns: pointer to @p if @p is NULL will return NULL
     286                 :            :  * Requires: @p must be held with valid refcount when called
     287                 :            :  */
     288                 :            : static inline struct aa_profile *aa_get_profile_not0(struct aa_profile *p)
     289                 :            : {
     290 [ #  # ][ #  # ]:          0 :         if (p && kref_get_not0(&p->count))
     291                 :            :                 return p;
     292                 :            : 
     293                 :            :         return NULL;
     294                 :            : }
     295                 :            : 
     296                 :            : /**
     297                 :            :  * aa_get_profile_rcu - increment a refcount profile that can be replaced
     298                 :            :  * @p: pointer to profile that can be replaced (NOT NULL)
     299                 :            :  *
     300                 :            :  * Returns: pointer to a refcounted profile.
     301                 :            :  *     else NULL if no profile
     302                 :            :  */
     303                 :            : static inline struct aa_profile *aa_get_profile_rcu(struct aa_profile __rcu **p)
     304                 :            : {
     305                 :            :         struct aa_profile *c;
     306                 :            : 
     307                 :            :         rcu_read_lock();
     308                 :            :         do {
     309                 :          0 :                 c = rcu_dereference(*p);
     310 [ #  # ][ #  # ]:       9013 :         } while (c && !kref_get_not0(&c->count));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
              [ #  #  - ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     311                 :            :         rcu_read_unlock();
     312                 :            : 
     313                 :            :         return c;
     314                 :            : }
     315                 :            : 
     316                 :            : /**
     317                 :            :  * aa_get_newest_profile - find the newest version of @profile
     318                 :            :  * @profile: the profile to check for newer versions of
     319                 :            :  *
     320                 :            :  * Returns: refcounted newest version of @profile taking into account
     321                 :            :  *          replacement, renames and removals
     322                 :            :  *          return @profile.
     323                 :            :  */
     324                 :            : static inline struct aa_profile *aa_get_newest_profile(struct aa_profile *p)
     325                 :            : {
     326 [ +  + ][ +  - ]:      58900 :         if (!p)
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     327                 :            :                 return NULL;
     328                 :            : 
     329 [ -  + ][ -  + ]:      58855 :         if (PROFILE_INVALID(p))
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     330                 :          0 :                 return aa_get_profile_rcu(&p->replacedby->profile);
     331                 :            : 
     332                 :            :         return aa_get_profile(p);
     333                 :            : }
     334                 :            : 
     335                 :            : /**
     336                 :            :  * aa_put_profile - decrement refcount on profile @p
     337                 :            :  * @p: profile  (MAYBE NULL)
     338                 :            :  */
     339                 :            : static inline void aa_put_profile(struct aa_profile *p)
     340                 :            : {
     341 [ #  # ][ #  # ]:    3626888 :         if (p)
         [ #  # ][ #  # ]
         [ #  # ][ +  +  
             #  #  #  # ]
           [ #  #  #  #  
           #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
           [ #  #  #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ +  + ]
         [ -  + ][ -  + ]
         [ #  # ][ #  # ]
           [ #  #  #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  # ]
                 [ #  # ]
     342                 :    1878773 :                 kref_put(&p->count, aa_free_profile_kref);
     343                 :            : }
     344                 :            : 
     345                 :            : static inline struct aa_replacedby *aa_get_replacedby(struct aa_replacedby *p)
     346                 :            : {
     347 [ #  # ][ #  # ]:          0 :         if (p)
     348                 :            :                 kref_get(&(p->count));
     349                 :            : 
     350                 :            :         return p;
     351                 :            : }
     352                 :            : 
     353                 :            : static inline void aa_put_replacedby(struct aa_replacedby *p)
     354                 :            : {
     355         [ #  # ]:          0 :         if (p)
           [ #  #  #  # ]
                 [ #  # ]
     356                 :          0 :                 kref_put(&p->count, aa_free_replacedby_kref);
     357                 :            : }
     358                 :            : 
     359                 :            : /* requires profile list write lock held */
     360                 :            : static inline void __aa_update_replacedby(struct aa_profile *orig,
     361                 :            :                                           struct aa_profile *new)
     362                 :            : {
     363                 :            :         struct aa_profile *tmp;
     364                 :          0 :         tmp = rcu_dereference_protected(orig->replacedby->profile,
     365                 :            :                                         mutex_is_locked(&orig->ns->lock));
     366                 :          0 :         rcu_assign_pointer(orig->replacedby->profile, aa_get_profile(new));
     367                 :          0 :         orig->flags |= PFLAG_INVALID;
     368                 :            :         aa_put_profile(tmp);
     369                 :            : }
     370                 :            : 
     371                 :            : /**
     372                 :            :  * aa_get_namespace - increment references count on @ns
     373                 :            :  * @ns: namespace to increment reference count of (MAYBE NULL)
     374                 :            :  *
     375                 :            :  * Returns: pointer to @ns, if @ns is NULL returns NULL
     376                 :            :  * Requires: @ns must be held with valid refcount when called
     377                 :            :  */
     378                 :            : static inline struct aa_namespace *aa_get_namespace(struct aa_namespace *ns)
     379                 :            : {
     380 [ #  # ][ #  # ]:          0 :         if (ns)
                 [ #  # ]
           [ #  #  #  # ]
           [ #  #  #  #  
                   #  # ]
     381                 :          0 :                 aa_get_profile(ns->unconfined);
     382                 :            : 
     383                 :            :         return ns;
     384                 :            : }
     385                 :            : 
     386                 :            : /**
     387                 :            :  * aa_put_namespace - decrement refcount on @ns
     388                 :            :  * @ns: namespace to put reference of
     389                 :            :  *
     390                 :            :  * Decrement reference count of @ns and if no longer in use free it
     391                 :            :  */
     392                 :            : static inline void aa_put_namespace(struct aa_namespace *ns)
     393                 :            : {
     394         [ #  # ]:          0 :         if (ns)
           [ #  #  #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  #  
             #  #  #  # ]
     395                 :          0 :                 aa_put_profile(ns->unconfined);
     396                 :            : }
     397                 :            : 
     398                 :            : static inline int AUDIT_MODE(struct aa_profile *profile)
     399                 :            : {
     400 [ #  # ][ #  # ]:          0 :         if (aa_g_audit != AUDIT_NORMAL)
                 [ #  # ]
     401                 :          0 :                 return aa_g_audit;
     402                 :            : 
     403                 :          0 :         return profile->audit;
     404                 :            : }
     405                 :            : 
     406                 :            : bool aa_may_manage_policy(int op);
     407                 :            : 
     408                 :            : #endif /* __AA_POLICY_H */

Generated by: LCOV version 1.9