summaryrefslogtreecommitdiff
path: root/security/apparmor/include/policy.h
diff options
context:
space:
mode:
Diffstat (limited to 'security/apparmor/include/policy.h')
-rw-r--r--security/apparmor/include/policy.h68
1 files changed, 44 insertions, 24 deletions
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index 545f791cabda..75088cc310b6 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -34,6 +34,7 @@
struct aa_ns;
extern int unprivileged_userns_apparmor_policy;
+extern int aa_unprivileged_unconfined_restricted;
extern const char *const aa_profile_mode_names[];
#define APPARMOR_MODE_NAMES_MAX_INDEX 4
@@ -74,12 +75,14 @@ enum profile_mode {
/* struct aa_policydb - match engine for a policy
+ * count: refcount for the pdb
* 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 {
+ struct kref count;
struct aa_dfa *dfa;
struct {
struct aa_perms *perms;
@@ -89,13 +92,36 @@ struct aa_policydb {
aa_state_t start[AA_CLASS_LAST + 1];
};
-static inline void aa_destroy_policydb(struct aa_policydb *policy)
+extern struct aa_policydb *nullpdb;
+
+struct aa_policydb *aa_alloc_pdb(gfp_t gfp);
+void aa_pdb_free_kref(struct kref *kref);
+
+/**
+ * aa_get_pdb - increment refcount on @pdb
+ * @pdb: policydb (MAYBE NULL)
+ *
+ * Returns: pointer to @pdb if @pdb is NULL will return NULL
+ * Requires: @pdb must be held with valid refcount when called
+ */
+static inline struct aa_policydb *aa_get_pdb(struct aa_policydb *pdb)
{
- aa_put_dfa(policy->dfa);
- if (policy->perms)
- kvfree(policy->perms);
- aa_free_str_table(&policy->trans);
+ if (pdb)
+ kref_get(&(pdb->count));
+
+ return pdb;
+}
+/**
+ * aa_put_pdb - put a pdb refcount
+ * @pdb: pdb to put refcount (MAYBE NULL)
+ *
+ * Requires: if @pdb != NULL that a valid refcount be held
+ */
+static inline void aa_put_pdb(struct aa_policydb *pdb)
+{
+ if (pdb)
+ kref_put(&pdb->count, aa_pdb_free_kref);
}
static inline struct aa_perms *aa_lookup_perms(struct aa_policydb *policy,
@@ -139,8 +165,8 @@ struct aa_ruleset {
int size;
/* TODO: merge policy and file */
- struct aa_policydb policy;
- struct aa_policydb file;
+ struct aa_policydb *policy;
+ struct aa_policydb *file;
struct aa_caps caps;
struct aa_rlimit rlimits;
@@ -159,7 +185,7 @@ struct aa_ruleset {
*/
struct aa_attachment {
const char *xmatch_str;
- struct aa_policydb xmatch;
+ struct aa_policydb *xmatch;
unsigned int xmatch_len;
int xattr_count;
char **xattrs;
@@ -227,10 +253,6 @@ extern enum profile_mode aa_g_profile_mode;
#define profiles_ns(P) ((P)->ns)
#define name_is_shared(A, B) ((A)->hname && (A)->hname == (B)->hname)
-void aa_add_profile(struct aa_policy *common, struct aa_profile *profile);
-
-
-void aa_free_proxy_kref(struct kref *kref);
struct aa_ruleset *aa_alloc_ruleset(gfp_t gfp);
struct aa_profile *aa_alloc_profile(const char *name, struct aa_proxy *proxy,
gfp_t gfp);
@@ -239,14 +261,12 @@ struct aa_profile *aa_alloc_null(struct aa_profile *parent, const char *name,
struct aa_profile *aa_new_learning_profile(struct aa_profile *parent, bool hat,
const char *base, gfp_t gfp);
void aa_free_profile(struct aa_profile *profile);
-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_lookupn_profile(struct aa_ns *ns, const char *hname,
size_t n);
struct aa_profile *aa_lookup_profile(struct aa_ns *ns, const char *name);
struct aa_profile *aa_fqlookupn_profile(struct aa_label *base,
const char *fqname, size_t n);
-struct aa_profile *aa_match_profile(struct aa_ns *ns, const char *name);
ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_label *label,
u32 mask, struct aa_loaddata *udata);
@@ -254,9 +274,6 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_label *label,
char *name, size_t size);
void __aa_profile_list_release(struct list_head *head);
-#define PROF_ADD 1
-#define PROF_REPLACE 0
-
#define profile_unconfined(X) ((X)->mode == APPARMOR_UNCONFINED)
/**
@@ -276,10 +293,10 @@ static inline aa_state_t RULE_MEDIATES(struct aa_ruleset *rules,
unsigned char class)
{
if (class <= AA_CLASS_LAST)
- return rules->policy.start[class];
+ return rules->policy->start[class];
else
- return aa_dfa_match_len(rules->policy.dfa,
- rules->policy.start[0], &class, 1);
+ return aa_dfa_match_len(rules->policy->dfa,
+ rules->policy->start[0], &class, 1);
}
static inline aa_state_t RULE_MEDIATES_AF(struct aa_ruleset *rules, u16 AF)
@@ -289,7 +306,7 @@ static inline aa_state_t RULE_MEDIATES_AF(struct aa_ruleset *rules, u16 AF)
if (!state)
return DFA_NOMATCH;
- return aa_dfa_match_len(rules->policy.dfa, state, (char *) &be_af, 2);
+ return aa_dfa_match_len(rules->policy->dfa, state, (char *) &be_af, 2);
}
static inline aa_state_t ANY_RULE_MEDIATES(struct list_head *head,
@@ -370,9 +387,12 @@ static inline int AUDIT_MODE(struct aa_profile *profile)
return profile->audit;
}
-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);
-int aa_may_manage_policy(struct aa_label *label, struct aa_ns *ns,
+bool aa_policy_view_capable(const struct cred *subj_cred,
+ struct aa_label *label, struct aa_ns *ns);
+bool aa_policy_admin_capable(const struct cred *subj_cred,
+ struct aa_label *label, struct aa_ns *ns);
+int aa_may_manage_policy(const struct cred *subj_cred,
+ struct aa_label *label, struct aa_ns *ns,
u32 mask);
bool aa_current_policy_view_capable(struct aa_ns *ns);
bool aa_current_policy_admin_capable(struct aa_ns *ns);