apparmor: add the ability for policy to specify a permission table
[linux-2.6-block.git] / security / apparmor / include / policy.h
index 639b5b248e63c796f7024fe3262976392b947805..2c39bd389f87823fb12ca705ec8cc4a5316030f5 100644 (file)
@@ -44,6 +44,8 @@ extern const char *const aa_profile_mode_names[];
 
 #define COMPLAIN_MODE(_profile)        PROFILE_MODE((_profile), APPARMOR_COMPLAIN)
 
+#define USER_MODE(_profile)    PROFILE_MODE((_profile), APPARMOR_USER)
+
 #define KILL_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_KILL)
 
 #define PROFILE_IS_HAT(_profile) ((_profile)->label.flags & FLAG_HAT)
@@ -67,20 +69,47 @@ enum profile_mode {
        APPARMOR_COMPLAIN,      /* allow and log access violations */
        APPARMOR_KILL,          /* kill task on access violation */
        APPARMOR_UNCONFINED,    /* profile set to unconfined */
+       APPARMOR_USER,          /* modified complain mode to userspace */
 };
 
 
 /* struct aa_policydb - match engine for a policy
  * dfa: dfa pattern match
+ * perms: table of permissions
+ * strs: table of strings, index by x
  * 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];
-
+       struct {
+               struct aa_perms *perms;
+               u32 size;
+       };
+       struct aa_str_table trans;
+       aa_state_t start[AA_CLASS_LAST + 1];
 };
 
+static inline void aa_destroy_policydb(struct aa_policydb *policy)
+{
+       aa_put_dfa(policy->dfa);
+       if (policy->perms)
+               kvfree(policy->perms);
+       aa_free_str_table(&policy->trans);
+
+}
+
+static inline struct aa_perms *aa_lookup_perms(struct aa_policydb *policy,
+                                              aa_state_t state)
+{
+       unsigned int index = ACCEPT_TABLE(policy->dfa)[state];
+
+       if (!(policy->perms))
+               return &default_perms;
+
+       return &(policy->perms[index]);
+}
+
+
 /* struct aa_data - generic data structure
  * key: name for retrieving this data
  * size: size of data in bytes
@@ -138,8 +167,9 @@ struct aa_profile {
        const char *rename;
 
        const char *attach;
-       struct aa_dfa *xmatch;
+       struct aa_policydb xmatch;
        unsigned int xmatch_len;
+
        enum audit_mode audit;
        long mode;
        u32 path_flags;
@@ -147,7 +177,7 @@ struct aa_profile {
        int size;
 
        struct aa_policydb policy;
-       struct aa_file_rules file;
+       struct aa_policydb file;
        struct aa_caps caps;
 
        int xattr_count;
@@ -217,7 +247,7 @@ static inline struct aa_profile *aa_get_newest_profile(struct aa_profile *p)
        return labels_profile(aa_get_newest_label(&p->label));
 }
 
-static inline unsigned int PROFILE_MEDIATES(struct aa_profile *profile,
+static inline aa_state_t PROFILE_MEDIATES(struct aa_profile *profile,
                                            unsigned char class)
 {
        if (class <= AA_CLASS_LAST)
@@ -227,13 +257,13 @@ static inline unsigned int PROFILE_MEDIATES(struct aa_profile *profile,
                                        profile->policy.start[0], &class, 1);
 }
 
-static inline unsigned int PROFILE_MEDIATES_AF(struct aa_profile *profile,
-                                              u16 AF) {
-       unsigned int state = PROFILE_MEDIATES(profile, AA_CLASS_NET);
+static inline aa_state_t PROFILE_MEDIATES_AF(struct aa_profile *profile,
+                                            u16 AF) {
+       aa_state_t state = PROFILE_MEDIATES(profile, AA_CLASS_NET);
        __be16 be_af = cpu_to_be16(AF);
 
        if (!state)
-               return 0;
+               return DFA_NOMATCH;
        return aa_dfa_match_len(profile->policy.dfa, state, (char *) &be_af, 2);
 }