summaryrefslogtreecommitdiff
path: root/security/apparmor/include
diff options
context:
space:
mode:
Diffstat (limited to 'security/apparmor/include')
-rw-r--r--security/apparmor/include/af_inet.h36
-rw-r--r--security/apparmor/include/apparmor.h1
-rw-r--r--security/apparmor/include/apparmorfs.h3
-rw-r--r--security/apparmor/include/audit.h10
-rw-r--r--security/apparmor/include/capability.h3
-rw-r--r--security/apparmor/include/cred.h22
-rw-r--r--security/apparmor/include/file.h2
-rw-r--r--security/apparmor/include/label.h31
-rw-r--r--security/apparmor/include/lib.h6
-rw-r--r--security/apparmor/include/match.h18
-rw-r--r--security/apparmor/include/net.h9
-rw-r--r--security/apparmor/include/path.h3
-rw-r--r--security/apparmor/include/perms.h19
-rw-r--r--security/apparmor/include/policy.h17
-rw-r--r--security/apparmor/include/policy_unpack.h4
-rw-r--r--security/apparmor/include/procattr.h2
-rw-r--r--security/apparmor/include/task.h20
17 files changed, 140 insertions, 66 deletions
diff --git a/security/apparmor/include/af_inet.h b/security/apparmor/include/af_inet.h
new file mode 100644
index 000000000000..601ab44bdfe1
--- /dev/null
+++ b/security/apparmor/include/af_inet.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor inet/inet6 fine grained mediation
+ *
+ * Copyright 2024 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_AF_INET_H
+#define __AA_AF_INET_H
+
+#include "label.h"
+
+int aa_inet_sock_perm(const char *op, u32 request, struct socket *sock);
+int aa_inet_create_perm(struct aa_label *label, int family, int type,
+ int protocol);
+int aa_inet_bind_perm(struct socket *sock, struct sockaddr *address,
+ int addrlen);
+int aa_inet_connect_perm(struct socket *sock, struct sockaddr *address,
+ int addrlen);
+int aa_inet_listen_perm(struct socket *sock, int backlog);
+int aa_inet_accept_perm(struct socket *sock, struct socket *newsock);
+int aa_inet_msg_perm(const char *op, u32 request, struct socket *sock,
+ struct msghdr *msg, int size);
+int aa_inet_opt_perm(const char *op, u32 request, struct socket *sock, int level,
+ int optname);
+int aa_inet_file_perm(const struct cred *subj_cred,
+ struct aa_label *label, const char *op, u32 request,
+ struct socket *sock);
+
+#endif /* __AA_AF_INET_H */
diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
index cc6e3df1bc62..cb06b2f55d49 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -36,6 +36,7 @@
#define AA_CLASS_NS 21
#define AA_CLASS_IO_URING 22
+#define AA_CLASS_NETV9_SKB 30
#define AA_CLASS_X 31
#define AA_CLASS_DBUS 32
diff --git a/security/apparmor/include/apparmorfs.h b/security/apparmor/include/apparmorfs.h
index 33243d11fd10..c6c8fcde728f 100644
--- a/security/apparmor/include/apparmorfs.h
+++ b/security/apparmor/include/apparmorfs.h
@@ -11,6 +11,9 @@
#ifndef __AA_APPARMORFS_H
#define __AA_APPARMORFS_H
+#include <linux/init.h>
+#include <linux/types.h>
+
extern struct path aa_null;
enum aa_sfs_type {
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
index aa00b34404f9..987ed4441fd3 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -21,13 +21,14 @@
#include "label.h"
extern const char *const audit_mode_names[];
-#define AUDIT_MAX_INDEX 5
enum audit_mode {
AUDIT_NORMAL, /* follow normal auditing of accesses */
AUDIT_QUIET_DENIED, /* quiet all denied access messages */
+ AUDIT_QUIET_ALLOWED, /* quiet all allowed access messages */
AUDIT_QUIET, /* quiet all messages */
AUDIT_NOQUIET, /* do not quiet audit messages */
- AUDIT_ALL /* audit all accesses */
+ AUDIT_ALL, /* audit all accesses */
+ AUDIT_MODE_NAMES_COUNT /* Must be last entry */
};
enum audit_type {
@@ -183,6 +184,8 @@ struct apparmor_audit_data {
.common.apparmor_audit_data = &NAME, \
};
+int aa_select_audit_type(u32 denied, const struct aa_perms *perms);
+
void aa_audit_msg(int type, struct apparmor_audit_data *ad,
void (*cb) (struct audit_buffer *, void *));
int aa_audit(int type, struct aa_profile *profile,
@@ -196,6 +199,9 @@ int aa_audit(int type, struct aa_profile *profile,
(AD)->error; \
})
+int aa_audit_perm_error(struct aa_label *label, u32 request, int error,
+ struct apparmor_audit_data *ad,
+ void (*cb)(struct audit_buffer *, void *));
static inline int complain_error(int error)
{
diff --git a/security/apparmor/include/capability.h b/security/apparmor/include/capability.h
index 1ddcec2d1160..89a9c75d8f44 100644
--- a/security/apparmor/include/capability.h
+++ b/security/apparmor/include/capability.h
@@ -11,6 +11,7 @@
#ifndef __AA_CAPABILITY_H
#define __AA_CAPABILITY_H
+#include <linux/capability.h>
#include <linux/sched.h>
#include "apparmorfs.h"
@@ -36,7 +37,7 @@ struct aa_caps {
extern struct aa_sfs_entry aa_sfs_entry_caps[];
-kernel_cap_t aa_profile_capget(struct aa_profile *profile);
+kernel_cap_t aa_profile_capget(const struct aa_profile *profile);
int aa_capable(const struct cred *subj_cred, struct aa_label *label,
int cap, unsigned int opts);
diff --git a/security/apparmor/include/cred.h b/security/apparmor/include/cred.h
index 2b6098149b15..056e031b7b8a 100644
--- a/security/apparmor/include/cred.h
+++ b/security/apparmor/include/cred.h
@@ -177,12 +177,14 @@ static inline void __end_current_label_crit_section(struct aa_label *label,
/**
* end_current_label_crit_section - put a reference found with begin_current_label..
* @label: label reference to put
+ * @needput: output: bool set by __begin_current_label_crit_section
*
* Should only be used with a reference obtained with
* begin_current_label_crit_section and never used in situations where the
* task cred may be updated
*/
-static inline void end_current_label_crit_section(struct aa_label *label)
+static inline void end_current_label_crit_section(struct aa_label *label,
+ bool needput)
{
if (label != aa_current_raw_label())
aa_put_label(label);
@@ -208,28 +210,22 @@ static inline struct aa_label *__begin_current_label_crit_section(bool *needput)
/**
* begin_current_label_crit_section - current's confining label and update it
+ * @needput: store whether the label needs to be put when ending crit section
*
* Returns: up to date confining label or the ns unconfined label (NOT NULL)
*
- * Not safe to call inside locks
- *
* The returned reference must be put with end_current_label_crit_section()
- * This must NOT be used if the task cred could be updated within the
+ * This should NOT be used if the task cred could be updated within the
* critical section between begin_current_label_crit_section() ..
* end_current_label_crit_section()
*/
-static inline struct aa_label *begin_current_label_crit_section(void)
+static inline struct aa_label *begin_current_label_crit_section(bool *needput)
{
struct aa_label *label = aa_current_raw_label();
- might_sleep();
-
- if (label_is_stale(label)) {
- label = aa_get_newest_label(label);
- if (aa_replace_current_label(label) == 0)
- /* task cred will keep the reference */
- aa_put_label(label);
- }
+ label = __begin_current_label_crit_section(needput);
+ if (*needput)
+ aa_schedule_stale_label_replacement();
return label;
}
diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
index ef60f99bc5ae..1614c07fc53e 100644
--- a/security/apparmor/include/file.h
+++ b/security/apparmor/include/file.h
@@ -72,7 +72,7 @@ struct path_cond {
#define COMBINED_PERM_MASK(X) ((X).allow | (X).audit | (X).quiet | (X).kill)
int aa_audit_file(const struct cred *cred,
- struct aa_profile *profile, struct aa_perms *perms,
+ struct aa_profile *profile, const struct aa_perms *perms,
const char *op, u32 request, const char *name,
const char *target, struct aa_label *tlabel, kuid_t ouid,
const char *info, int error);
diff --git a/security/apparmor/include/label.h b/security/apparmor/include/label.h
index b5a722a47fd2..2c869b7dec97 100644
--- a/security/apparmor/include/label.h
+++ b/security/apparmor/include/label.h
@@ -23,7 +23,7 @@ struct aa_ruleset;
#define LOCAL_VEC_ENTRIES 8
#define DEFINE_VEC(T, V) \
- struct aa_ ## T *(_ ## V ## _localtmp)[LOCAL_VEC_ENTRIES]; \
+ struct aa_ ## T *(_ ## V ## _localtmp)[LOCAL_VEC_ENTRIES + 1]; \
struct aa_ ## T **(V)
#define vec_setup(T, V, N, GFP) \
@@ -31,10 +31,10 @@ struct aa_ruleset;
if ((N) <= LOCAL_VEC_ENTRIES) { \
typeof(N) i; \
(V) = (_ ## V ## _localtmp); \
- for (i = 0; i < (N); i++) \
+ for (i = 0; i <= (N); i++) \
(V)[i] = NULL; \
} else \
- (V) = kzalloc(sizeof(struct aa_ ## T *) * (N), (GFP)); \
+ (V) = kzalloc_objs(struct aa_ ## T *, (N) + 1, (GFP)); \
(V) ? 0 : -ENOMEM; \
})
@@ -165,7 +165,7 @@ do { \
#define labels_profile(X) ((X)->vec[(X)->size - 1])
-int aa_label_next_confined(struct aa_label *l, int i);
+int aa_label_next_confined(const struct aa_label *l, int i);
/* for each profile in a label */
#define label_for_each(I, L, P) \
@@ -246,12 +246,12 @@ int aa_label_next_confined(struct aa_label *l, int i);
#define fn_for_each_not_in_set(L1, L2, P, FN) \
fn_for_each2_XXX((L1), (L2), P, FN, _not_in_set)
-static inline bool label_mediates(struct aa_label *L, unsigned char C)
+static inline bool label_mediates(const struct aa_label *L, unsigned char C)
{
return (L)->mediates & (((u64) 1) << (C));
}
-static inline bool label_mediates_safe(struct aa_label *L, unsigned char C)
+static inline bool label_mediates_safe(const struct aa_label *L, unsigned char C)
{
if (C > AA_CLASS_LAST)
return false;
@@ -268,11 +268,12 @@ void aa_label_kref(struct kref *kref);
bool aa_label_init(struct aa_label *label, int size, gfp_t gfp);
struct aa_label *aa_label_alloc(int size, struct aa_proxy *proxy, gfp_t gfp);
-bool aa_label_is_subset(struct aa_label *set, struct aa_label *sub);
-bool aa_label_is_unconfined_subset(struct aa_label *set, struct aa_label *sub);
+bool aa_label_is_subset(const struct aa_label *set, const struct aa_label *sub);
+bool aa_label_is_unconfined_subset(const struct aa_label *set,
+ const struct aa_label *sub);
struct aa_profile *__aa_label_next_not_in_set(struct label_it *I,
- struct aa_label *set,
- struct aa_label *sub);
+ const struct aa_label *set,
+ const struct aa_label *sub);
bool aa_label_remove(struct aa_label *label);
struct aa_label *aa_label_insert(struct aa_labelset *ls, struct aa_label *l);
bool aa_label_replace(struct aa_label *old, struct aa_label *new);
@@ -280,8 +281,8 @@ bool aa_label_make_newest(struct aa_labelset *ls, struct aa_label *old,
struct aa_label *new);
struct aa_profile *aa_label_next_in_merge(struct label_it *I,
- struct aa_label *a,
- struct aa_label *b);
+ const struct aa_label *a,
+ const struct aa_label *b);
struct aa_label *aa_label_find_merge(struct aa_label *a, struct aa_label *b);
struct aa_label *aa_label_merge(struct aa_label *a, struct aa_label *b,
gfp_t gfp);
@@ -342,7 +343,7 @@ static inline const char *aa_label_str_split(const char *str)
struct aa_perms;
struct aa_ruleset;
-int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules,
+int aa_label_match(const struct aa_profile *profile, struct aa_ruleset *rules,
struct aa_label *label, aa_state_t state, bool subns,
u32 request, struct aa_perms *perms);
@@ -462,8 +463,8 @@ static inline void aa_put_label(struct aa_label *l)
}
/* wrapper fn to indicate semantics of the check */
-static inline bool __aa_subj_label_is_cached(struct aa_label *subj_label,
- struct aa_label *obj_label)
+static inline bool __aa_subj_label_is_cached(const struct aa_label *subj_label,
+ const struct aa_label *obj_label)
{
return aa_label_is_subset(obj_label, subj_label);
}
diff --git a/security/apparmor/include/lib.h b/security/apparmor/include/lib.h
index e3c8cb044a90..475dd71fbe40 100644
--- a/security/apparmor/include/lib.h
+++ b/security/apparmor/include/lib.h
@@ -136,7 +136,7 @@ static inline bool aa_strneq(const char *str, const char *sub, int len)
* character which is not used in standard matching and is only
* used to separate pairs.
*/
-static inline aa_state_t aa_dfa_null_transition(struct aa_dfa *dfa,
+static inline aa_state_t aa_dfa_null_transition(const struct aa_dfa *dfa,
aa_state_t start)
{
/* the null transition only needs the string's null terminator byte */
@@ -338,8 +338,8 @@ __do_cleanup: \
__new_ = (FN); \
} \
__done: \
- if (PTR_ERR(__new_)) \
- AA_DEBUG(DEBUG_LABEL, "label build failed\n"); \
+ if (IS_ERR(__new_)) \
+ AA_DEBUG(DEBUG_LABEL, "label build failed %ld\n", PTR_ERR(__new_)); \
(__new_); \
})
diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h
index 7accb1c39849..f7bd7855f1bd 100644
--- a/security/apparmor/include/match.h
+++ b/security/apparmor/include/match.h
@@ -125,16 +125,18 @@ static inline size_t table_size(size_t len, size_t el_size)
#define aa_state_t unsigned int
-struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags);
-aa_state_t aa_dfa_match_len(struct aa_dfa *dfa, aa_state_t start,
+struct aa_dfa *aa_dfa_unpack(const void *blob, size_t size, int flags);
+aa_state_t aa_dfa_match_len(const struct aa_dfa *dfa, aa_state_t start,
const char *str, int len);
-aa_state_t aa_dfa_match(struct aa_dfa *dfa, aa_state_t start,
+aa_state_t aa_dfa_match(const struct aa_dfa *dfa, aa_state_t start,
const char *str);
-aa_state_t aa_dfa_next(struct aa_dfa *dfa, aa_state_t state, const char c);
-aa_state_t aa_dfa_outofband_transition(struct aa_dfa *dfa, aa_state_t state);
-aa_state_t aa_dfa_match_until(struct aa_dfa *dfa, aa_state_t start,
+aa_state_t aa_dfa_next(const struct aa_dfa *dfa, aa_state_t state,
+ const char c);
+aa_state_t aa_dfa_outofband_transition(const struct aa_dfa *dfa,
+ aa_state_t state);
+aa_state_t aa_dfa_match_until(const struct aa_dfa *dfa, aa_state_t start,
const char *str, const char **retpos);
-aa_state_t aa_dfa_matchn_until(struct aa_dfa *dfa, aa_state_t start,
+aa_state_t aa_dfa_matchn_until(const struct aa_dfa *dfa, aa_state_t start,
const char *str, int n, const char **retpos);
void aa_dfa_free_kref(struct kref *kref);
@@ -152,7 +154,7 @@ struct match_workbuf N = { \
.len = 0, \
}
-aa_state_t aa_dfa_leftmatch(struct aa_dfa *dfa, aa_state_t start,
+aa_state_t aa_dfa_leftmatch(const struct aa_dfa *dfa, aa_state_t start,
const char *str, unsigned int *count);
/**
diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
index 0d0b0ce42723..375341929cb6 100644
--- a/security/apparmor/include/net.h
+++ b/security/apparmor/include/net.h
@@ -86,7 +86,7 @@ extern struct aa_sfs_entry aa_sfs_entry_network[];
extern struct aa_sfs_entry aa_sfs_entry_networkv9[];
int aa_do_perms(struct aa_profile *profile, struct aa_policydb *policy,
- aa_state_t state, u32 request, struct aa_perms *p,
+ aa_state_t state, u32 request, const struct aa_perms *p,
struct apparmor_audit_data *ad);
/* passing in state returned by XXX_mediates_AF() */
aa_state_t aa_match_to_prot(struct aa_policydb *policy, aa_state_t state,
@@ -102,13 +102,14 @@ int aa_af_perm(const struct cred *subj_cred, struct aa_label *label,
static inline int aa_profile_af_sk_perm(struct aa_profile *profile,
struct apparmor_audit_data *ad,
u32 request,
- struct sock *sk)
+ const struct sock *sk)
{
return aa_profile_af_perm(profile, ad, request, sk->sk_family,
sk->sk_type, sk->sk_protocol);
}
-int aa_sk_perm(const char *op, u32 request, struct sock *sk);
-
+int aa_sk_perm(const char *op, u32 request, const struct sock *sk);
+int aa_label_sk_perm(const struct cred *subj_cred, struct aa_label *label,
+ const char *op, u32 request, const struct sock *sk);
int aa_sock_file_perm(const struct cred *subj_cred, struct aa_label *label,
const char *op, u32 request,
struct file *file);
diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h
index 8bb915d48dc7..250812a77e11 100644
--- a/security/apparmor/include/path.h
+++ b/security/apparmor/include/path.h
@@ -11,6 +11,9 @@
#ifndef __AA_PATH_H
#define __AA_PATH_H
+#include <linux/path.h>
+#include <linux/types.h>
+
enum path_flags {
PATH_IS_DIR = 0x1, /* path is a directory */
PATH_SOCK_COND = 0x2,
diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h
index 37a3781b99a0..ee25eb8e78e4 100644
--- a/security/apparmor/include/perms.h
+++ b/security/apparmor/include/perms.h
@@ -96,8 +96,8 @@ struct aa_perms {
#define AA_INDEX_NONE 0
#define ALL_PERMS_MASK 0xffffffff
-extern struct aa_perms nullperms;
-extern struct aa_perms allperms;
+extern const struct aa_perms nullperms;
+extern const struct aa_perms allperms;
/**
* aa_perms_accum_raw - accumulate perms with out masking off overlapping perms
@@ -105,7 +105,7 @@ extern struct aa_perms allperms;
* @addend: perms struct to add to @accum
*/
static inline void aa_perms_accum_raw(struct aa_perms *accum,
- struct aa_perms *addend)
+ const struct aa_perms *addend)
{
accum->deny |= addend->deny;
accum->allow &= addend->allow & ~addend->deny;
@@ -132,7 +132,7 @@ static inline void aa_perms_accum_raw(struct aa_perms *accum,
* @addend: perms struct to add to @accum
*/
static inline void aa_perms_accum(struct aa_perms *accum,
- struct aa_perms *addend)
+ const struct aa_perms *addend)
{
accum->deny |= addend->deny;
accum->allow &= addend->allow & ~accum->deny;
@@ -206,14 +206,15 @@ void aa_audit_perm_names(struct audit_buffer *ab, const char * const *names,
u32 mask);
void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
u32 chrsmask, const char * const *names, u32 namesmask);
-void aa_apply_modes_to_perms(struct aa_profile *profile,
+void aa_apply_modes_to_perms(const struct aa_profile *profile,
struct aa_perms *perms);
-void aa_perms_accum(struct aa_perms *accum, struct aa_perms *addend);
-void aa_perms_accum_raw(struct aa_perms *accum, struct aa_perms *addend);
-void aa_profile_match_label(struct aa_profile *profile,
+void aa_perms_accum(struct aa_perms *accum, const struct aa_perms *addend);
+void aa_perms_accum_raw(struct aa_perms *accum, const struct aa_perms *addend);
+void aa_profile_match_label(const struct aa_profile *profile,
struct aa_ruleset *rules, struct aa_label *label,
int type, u32 request, struct aa_perms *perms);
-int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms,
+int aa_check_perms(struct aa_profile *profile, const struct aa_perms *perms,
u32 request, struct apparmor_audit_data *ad,
void (*cb)(struct audit_buffer *, void *));
#endif /* __AA_PERM_H */
+
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index 3895f8774a3f..0dcbf8cf1029 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -26,7 +26,6 @@
#include "file.h"
#include "lib.h"
#include "label.h"
-#include "net.h"
#include "perms.h"
#include "resource.h"
@@ -37,7 +36,6 @@ 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
#define PROFILE_MODE(_profile, _mode) \
((aa_g_profile_mode == (_mode)) || \
@@ -76,6 +74,7 @@ enum profile_mode {
APPARMOR_KILL, /* kill task on access violation */
APPARMOR_UNCONFINED, /* profile set to unconfined */
APPARMOR_USER, /* modified complain mode to userspace */
+ PROFILE_MODE_NAMES_COUNT /* Must be last entry */
};
@@ -295,6 +294,9 @@ struct aa_profile *aa_alloc_profile(const char *name, struct aa_proxy *proxy,
gfp_t gfp);
struct aa_profile *aa_alloc_null(struct aa_profile *parent, const char *name,
gfp_t gfp);
+struct aa_profile *__aa_new_learning_profile(struct aa_profile *parent,
+ bool hat, const char *base,
+ gfp_t gfp);
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);
@@ -305,7 +307,8 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_label *base,
const char *fqname, size_t n);
ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_label *label,
- u32 mask, struct aa_loaddata *udata);
+ u32 mask, struct aa_loaddata *udata,
+ char *compressed_profile, size_t compressed_size);
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);
@@ -351,10 +354,14 @@ static inline aa_state_t RULE_MEDIATES_NET(struct aa_ruleset *rules)
/* fallback and check v7/8 if v9 is NOT mediated */
if (!state)
state = RULE_MEDIATES(rules, AA_CLASS_NET);
-
return state;
}
+static inline aa_state_t RULE_MEDIATES_UNIX(struct aa_ruleset *rules)
+{
+ return RULE_MEDIATES_v9NET(rules);
+}
+
void aa_compute_profile_mediates(struct aa_profile *profile);
static inline bool profile_mediates(struct aa_profile *profile,
@@ -429,7 +436,7 @@ static inline void aa_put_profile(struct aa_profile *p)
kref_put(&p->label.count.count, aa_label_kref);
}
-static inline int AUDIT_MODE(struct aa_profile *profile)
+static inline int AUDIT_MODE(const struct aa_profile *profile)
{
if (aa_g_audit != AUDIT_NORMAL)
return aa_g_audit;
diff --git a/security/apparmor/include/policy_unpack.h b/security/apparmor/include/policy_unpack.h
index 4ea9b6479a3e..c01f6885dbe3 100644
--- a/security/apparmor/include/policy_unpack.h
+++ b/security/apparmor/include/policy_unpack.h
@@ -16,6 +16,7 @@
#include <linux/dcache.h>
#include <linux/workqueue.h>
+#include "lib.h"
struct aa_load_ent {
struct list_head list;
@@ -128,7 +129,8 @@ struct aa_loaddata {
char *data;
};
-int aa_unpack(struct aa_loaddata *udata, struct list_head *lh, const char **ns);
+int aa_unpack(struct aa_loaddata *udata, struct list_head *lh, const char **ns,
+ char *compressed_data, size_t compressed_size);
/**
* aa_get_i_loaddata - get a reference count from a counted data reference
diff --git a/security/apparmor/include/procattr.h b/security/apparmor/include/procattr.h
index 03dbfdb2f2c0..56acd1bdb634 100644
--- a/security/apparmor/include/procattr.h
+++ b/security/apparmor/include/procattr.h
@@ -11,6 +11,8 @@
#ifndef __AA_PROCATTR_H
#define __AA_PROCATTR_H
+#include "label.h"
+
int aa_getprocattr(struct aa_label *label, char **string, bool newline);
int aa_setprocattr_changehat(char *args, size_t size, int flags);
diff --git a/security/apparmor/include/task.h b/security/apparmor/include/task.h
index b1aaaf60fa8b..a8030ed78ff2 100644
--- a/security/apparmor/include/task.h
+++ b/security/apparmor/include/task.h
@@ -10,6 +10,11 @@
#ifndef __AA_TASK_H
#define __AA_TASK_H
+#include <linux/sched.h>
+
+#include "audit.h"
+#include "label.h"
+
static inline struct aa_task_ctx *task_ctx(struct task_struct *task)
{
return task->security + apparmor_blob_sizes.lbs_task;
@@ -21,15 +26,22 @@ static inline struct aa_task_ctx *task_ctx(struct task_struct *task)
* @onexec: profile to transition to on next exec (MAY BE NULL)
* @previous: profile the task may return to (MAY BE NULL)
* @token: magic value the task must know for returning to @previous_profile
+ * @label_replacement_tw: for aa_schedule_stale_label_replacement()
+ * @label_replacement_pending: is @label_replacement_tw pending?
+ *
+ * When changing this, check if aa_dup_task_ctx() needs to be updated.
*/
struct aa_task_ctx {
struct aa_label *nnp;
struct aa_label *onexec;
struct aa_label *previous;
u64 token;
+ struct callback_head label_replacement_tw;
+ bool label_replacement_pending;
};
int aa_replace_current_label(struct aa_label *label);
+void aa_schedule_stale_label_replacement(void);
void aa_set_current_onexec(struct aa_label *label, bool stack);
int aa_set_current_hat(struct aa_label *label, u64 token);
int aa_restore_previous_label(u64 cookie);
@@ -56,10 +68,10 @@ static inline void aa_free_task_ctx(struct aa_task_ctx *ctx)
static inline void aa_dup_task_ctx(struct aa_task_ctx *new,
const struct aa_task_ctx *old)
{
- *new = *old;
- aa_get_label(new->nnp);
- aa_get_label(new->previous);
- aa_get_label(new->onexec);
+ new->nnp = aa_get_label(old->nnp);
+ new->onexec = aa_get_label(old->onexec);
+ new->previous = aa_get_label(old->previous);
+ new->token = old->token;
}
/**