summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2022-09-05 20:47:36 -0700
committerJohn Johansen <john.johansen@canonical.com>2022-10-03 14:49:04 -0700
commit1ad22fcc4d0d2fb2e0f35aed555a86d016d5e590 (patch)
tree5cf7b9f785d46441d3c184a3097659eb7c2574ac
parent217af7e2f4deb629aaa49622685ccfee923898ca (diff)
apparmor: rework profile->rules to be a list
Convert profile->rules to a list as the next step towards supporting multiple rulesets in a profile. For this step only support a single list entry item. The logic for iterating the list will come as a separate step. Signed-off-by: John Johansen <john.johansen@canonical.com>
-rw-r--r--security/apparmor/apparmorfs.c3
-rw-r--r--security/apparmor/capability.c6
-rw-r--r--security/apparmor/domain.c24
-rw-r--r--security/apparmor/file.c6
-rw-r--r--security/apparmor/include/policy.h17
-rw-r--r--security/apparmor/ipc.c5
-rw-r--r--security/apparmor/lib.c6
-rw-r--r--security/apparmor/lsm.c7
-rw-r--r--security/apparmor/mount.c13
-rw-r--r--security/apparmor/net.c6
-rw-r--r--security/apparmor/policy.c37
-rw-r--r--security/apparmor/policy_ns.c6
-rw-r--r--security/apparmor/policy_unpack.c34
-rw-r--r--security/apparmor/resource.c19
-rw-r--r--security/apparmor/task.c10
15 files changed, 142 insertions, 57 deletions
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 84ef8b400b40..f6d83ffde3c4 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -611,7 +611,8 @@ static const struct file_operations aa_fs_ns_revision_fops = {
static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
const char *match_str, size_t match_len)
{
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
struct aa_perms tmp = { };
aa_state_t state = DFA_NOMATCH;
diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c
index b66ec63e2a48..326a51838ef2 100644
--- a/security/apparmor/capability.c
+++ b/security/apparmor/capability.c
@@ -64,7 +64,8 @@ static void audit_cb(struct audit_buffer *ab, void *va)
static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,
int cap, int error)
{
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
struct audit_cache *ent;
int type = AUDIT_APPARMOR_AUTO;
@@ -115,7 +116,8 @@ static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,
static int profile_capable(struct aa_profile *profile, int cap,
unsigned int opts, struct common_audit_data *sa)
{
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
int error;
if (cap_raised(rules->caps.allow, cap) &&
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index ad035d14cfc5..d4b09f061aee 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -81,7 +81,8 @@ static inline aa_state_t match_component(struct aa_profile *profile,
struct aa_profile *tp,
bool stack, aa_state_t state)
{
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
const char *ns_name;
if (stack)
@@ -118,7 +119,8 @@ static int label_compound_match(struct aa_profile *profile,
aa_state_t state, bool subns, u32 request,
struct aa_perms *perms)
{
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
struct aa_profile *tp;
struct label_it i;
struct path_cond cond = { };
@@ -179,7 +181,8 @@ static int label_components_match(struct aa_profile *profile,
aa_state_t start, bool subns, u32 request,
struct aa_perms *perms)
{
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
struct aa_profile *tp;
struct label_it i;
struct aa_perms tmp;
@@ -503,7 +506,8 @@ static const char *next_name(int xtype, const char *name)
struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
const char **name)
{
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
struct aa_label *label = NULL;
u32 xtype = xindex & AA_X_TYPE_MASK;
int index = xindex & AA_X_INDEX_MASK;
@@ -553,7 +557,8 @@ static struct aa_label *x_to_label(struct aa_profile *profile,
const char **lookupname,
const char **info)
{
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
struct aa_label *new = NULL;
struct aa_ns *ns = profile->ns;
u32 xtype = xindex & AA_X_TYPE_MASK;
@@ -620,7 +625,8 @@ static struct aa_label *profile_transition(struct aa_profile *profile,
char *buffer, struct path_cond *cond,
bool *secure_exec)
{
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
struct aa_label *new = NULL;
const char *info = NULL, *name = NULL, *target = NULL;
aa_state_t state = rules->file.start[AA_CLASS_FILE];
@@ -719,7 +725,8 @@ static int profile_onexec(struct aa_profile *profile, struct aa_label *onexec,
char *buffer, struct path_cond *cond,
bool *secure_exec)
{
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
aa_state_t state = rules->file.start[AA_CLASS_FILE];
struct aa_perms perms = {};
const char *xname = NULL, *info = "change_profile onexec";
@@ -1259,7 +1266,8 @@ static int change_profile_perms_wrapper(const char *op, const char *name,
struct aa_label *target, bool stack,
u32 request, struct aa_perms *perms)
{
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
const char *info = NULL;
int error = 0;
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index ef5d98f81a2b..d7f27848e7cc 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -224,7 +224,8 @@ int __aa_path_perm(const char *op, struct aa_profile *profile, const char *name,
u32 request, struct path_cond *cond, int flags,
struct aa_perms *perms)
{
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
int e = 0;
if (profile_unconfined(profile))
@@ -317,7 +318,8 @@ static int profile_path_link(struct aa_profile *profile,
const struct path *target, char *buffer2,
struct path_cond *cond)
{
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
const char *lname, *tname = NULL;
struct aa_perms lperms = {}, perms;
const char *info = NULL;
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index 9ee2c05e2895..5cadfb20df29 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -124,6 +124,7 @@ struct aa_data {
};
/* struct aa_ruleset - data covering mediation rules
+ * @list: list the rule is on
* @size: the memory consumed by this ruleset
* @policy: general match rules governing policy
* @file: The set of rules governing basic file access and domain transitions
@@ -133,6 +134,8 @@ struct aa_data {
* @secmark: secmark label match info
*/
struct aa_ruleset {
+ struct list_head list;
+
int size;
/* TODO: merge policy and file */
@@ -147,6 +150,7 @@ struct aa_ruleset {
};
/* struct aa_attachment - data and rules for a profiles attachment
+ * @list:
* @xmatch_str: human readable attachment string
* @xmatch: optional extended matching for unconfined executables names
* @xmatch_len: xmatch prefix len, used to determine xmatch priority
@@ -204,7 +208,7 @@ struct aa_profile {
const char *disconnected;
struct aa_attachment attach;
- struct aa_ruleset rules;
+ struct list_head rules;
struct aa_loaddata *rawdata;
unsigned char *hash;
@@ -227,6 +231,7 @@ 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);
struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
@@ -285,6 +290,16 @@ static inline aa_state_t RULE_MEDIATES_AF(struct aa_ruleset *rules, u16 AF)
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,
+ unsigned char class)
+{
+ struct aa_ruleset *rule;
+
+ /* TODO: change to list walk */
+ rule = list_first_entry(head, typeof(*rule), list);
+ return RULE_MEDIATES(rule, class);
+}
+
/**
* aa_get_profile - increment refcount on profile @p
* @p: profile (MAYBE NULL)
diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
index dc2fa548312d..1d4099385bdf 100644
--- a/security/apparmor/ipc.c
+++ b/security/apparmor/ipc.c
@@ -78,12 +78,13 @@ static int profile_signal_perm(struct aa_profile *profile,
struct aa_label *peer, u32 request,
struct common_audit_data *sa)
{
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
struct aa_perms perms;
aa_state_t state;
if (profile_unconfined(profile) ||
- !RULE_MEDIATES(rules, AA_CLASS_SIGNAL))
+ !ANY_RULE_MEDIATES(&profile->rules, AA_CLASS_SIGNAL))
return 0;
aad(sa)->peer = peer;
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
index ec73e51ca7e3..a630c951bb3b 100644
--- a/security/apparmor/lib.c
+++ b/security/apparmor/lib.c
@@ -351,14 +351,16 @@ int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target,
u32 request, int type, u32 *deny,
struct common_audit_data *sa)
{
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
struct aa_perms perms;
aad(sa)->label = &profile->label;
aad(sa)->peer = &target->label;
aad(sa)->request = request;
- aa_profile_match_label(profile, &profile->rules, &target->label, type,
- request, &perms);
+ aa_profile_match_label(profile, rules, &target->label, type, request,
+ &perms);
aa_apply_modes_to_perms(profile, &perms);
*deny |= request & perms.deny;
return aa_check_perms(profile, &perms, request, sa, aa_audit_perms_cb);
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 62f2ca32b959..a22e53e44123 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -163,12 +163,15 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
struct label_it i;
label_for_each_confined(i, label, profile) {
+ struct aa_ruleset *rules;
if (COMPLAIN_MODE(profile))
continue;
+ rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
*effective = cap_intersect(*effective,
- profile->rules.caps.allow);
+ rules->caps.allow);
*permitted = cap_intersect(*permitted,
- profile->rules.caps.allow);
+ rules->caps.allow);
}
}
rcu_read_unlock();
diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c
index d4724bdcb07f..cdfa430ae216 100644
--- a/security/apparmor/mount.c
+++ b/security/apparmor/mount.c
@@ -303,7 +303,8 @@ static int match_mnt_path_str(struct aa_profile *profile,
{
struct aa_perms perms = { };
const char *mntpnt = NULL, *info = NULL;
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
int pos, error;
AA_BUG(!profile);
@@ -359,12 +360,14 @@ static int match_mnt(struct aa_profile *profile, const struct path *path,
bool binary)
{
const char *devname = NULL, *info = NULL;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
int error = -EACCES;
AA_BUG(!profile);
AA_BUG(devpath && !devbuffer);
- if (!RULE_MEDIATES(&profile->rules, AA_CLASS_MOUNT))
+ if (!RULE_MEDIATES(rules, AA_CLASS_MOUNT))
return 0;
if (devpath) {
@@ -566,7 +569,8 @@ out:
static int profile_umount(struct aa_profile *profile, const struct path *path,
char *buffer)
{
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
struct aa_perms perms = { };
const char *name = NULL, *info = NULL;
aa_state_t state;
@@ -626,7 +630,8 @@ static struct aa_label *build_pivotroot(struct aa_profile *profile,
const struct path *old_path,
char *old_buffer)
{
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
const char *old_name, *new_name = NULL, *info = NULL;
const char *trans_name = NULL;
struct aa_perms perms = { };
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
index ae789ee834ad..788be1609a86 100644
--- a/security/apparmor/net.c
+++ b/security/apparmor/net.c
@@ -108,7 +108,8 @@ void audit_net_cb(struct audit_buffer *ab, void *va)
int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
u32 request, u16 family, int type)
{
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
struct aa_perms perms = { };
aa_state_t state;
__be16 buffer[2];
@@ -217,7 +218,8 @@ static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid,
{
int i, ret;
struct aa_perms perms = { };
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
if (rules->secmark_count == 0)
return 0;
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 74c0a3b34e9b..6f4cc8bfe03d 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -217,6 +217,17 @@ static void free_ruleset(struct aa_ruleset *rules)
kfree_sensitive(rules->secmark);
}
+struct aa_ruleset *aa_alloc_ruleset(gfp_t gfp)
+{
+ struct aa_ruleset *rules;
+
+ rules = kzalloc(sizeof(*rules), gfp);
+ if (rules)
+ INIT_LIST_HEAD(&rules->list);
+
+ return rules;
+}
+
/**
* aa_free_profile - free a profile
* @profile: the profile to free (MAYBE NULL)
@@ -229,6 +240,7 @@ static void free_ruleset(struct aa_ruleset *rules)
*/
void aa_free_profile(struct aa_profile *profile)
{
+ struct aa_ruleset *rule, *tmp;
struct rhashtable *rht;
AA_DEBUG("%s(%p)\n", __func__, profile);
@@ -244,7 +256,15 @@ void aa_free_profile(struct aa_profile *profile)
kfree_sensitive(profile->rename);
free_attachment(&profile->attach);
- free_ruleset(&profile->rules);
+
+ /*
+ * at this point there are no tasks that can have a reference
+ * to rules
+ */
+ list_for_each_entry_safe(rule, tmp, &profile->rules, list) {
+ list_del_init(&rule->list);
+ free_ruleset(rule);
+ }
kfree_sensitive(profile->dirname);
if (profile->data) {
@@ -272,6 +292,7 @@ struct aa_profile *aa_alloc_profile(const char *hname, struct aa_proxy *proxy,
gfp_t gfp)
{
struct aa_profile *profile;
+ struct aa_ruleset *rules;
/* freed by free_profile - usually through aa_put_profile */
profile = kzalloc(struct_size(profile, label.vec, 2), gfp);
@@ -283,6 +304,14 @@ struct aa_profile *aa_alloc_profile(const char *hname, struct aa_proxy *proxy,
if (!aa_label_init(&profile->label, 1, gfp))
goto fail;
+ INIT_LIST_HEAD(&profile->rules);
+
+ /* allocate the first ruleset, but leave it empty */
+ rules = aa_alloc_ruleset(gfp);
+ if (!rules)
+ goto fail;
+ list_add(&rules->list, &profile->rules);
+
/* update being set needed by fs interface */
if (!proxy) {
proxy = aa_alloc_proxy(&profile->label, gfp);
@@ -516,6 +545,7 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_label *base,
struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
const char *base, gfp_t gfp)
{
+ struct aa_ruleset *rules;
struct aa_profile *p, *profile;
const char *bname;
char *name = NULL;
@@ -558,8 +588,9 @@ name:
/* released on free_profile */
rcu_assign_pointer(profile->parent, aa_get_profile(parent));
profile->ns = aa_get_ns(parent->ns);
- profile->rules.file.dfa = aa_get_dfa(nulldfa);
- profile->rules.policy.dfa = aa_get_dfa(nulldfa);
+ rules = list_first_entry(&profile->rules, typeof(*rules), list);
+ rules->file.dfa = aa_get_dfa(nulldfa);
+ rules->policy.dfa = aa_get_dfa(nulldfa);
mutex_lock_nested(&profile->ns->lock, profile->ns->level);
p = __find_child(&parent->base.profiles, bname);
diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
index cb10994cd3b6..121aa79bccaa 100644
--- a/security/apparmor/policy_ns.c
+++ b/security/apparmor/policy_ns.c
@@ -83,6 +83,7 @@ const char *aa_ns_name(struct aa_ns *curr, struct aa_ns *view, bool subns)
static struct aa_profile *alloc_unconfined(const char *name)
{
struct aa_profile *profile;
+ struct aa_ruleset *rules;
profile = aa_alloc_profile(name, NULL, GFP_KERNEL);
if (!profile)
@@ -91,8 +92,9 @@ static struct aa_profile *alloc_unconfined(const char *name)
profile->label.flags |= FLAG_IX_ON_NAME_ERROR |
FLAG_IMMUTIBLE | FLAG_NS_COUNT | FLAG_UNCONFINED;
profile->mode = APPARMOR_UNCONFINED;
- profile->rules.file.dfa = aa_get_dfa(nulldfa);
- profile->rules.policy.dfa = aa_get_dfa(nulldfa);
+ rules = list_first_entry(&profile->rules, typeof(*rules), list);
+ rules->file.dfa = aa_get_dfa(nulldfa);
+ rules->policy.dfa = aa_get_dfa(nulldfa);
return profile;
}
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index bbca7772dfa2..ac9955ef5d4a 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -577,9 +577,8 @@ fail:
return false;
}
-static bool unpack_secmark(struct aa_ext *e, struct aa_profile *profile)
+static bool unpack_secmark(struct aa_ext *e, struct aa_ruleset *rules)
{
- struct aa_ruleset *rules = &profile->rules;
void *pos = e->pos;
u16 size;
int i;
@@ -624,7 +623,7 @@ fail:
return false;
}
-static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
+static bool unpack_rlimits(struct aa_ext *e, struct aa_ruleset *rules)
{
void *pos = e->pos;
@@ -635,7 +634,7 @@ static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
u32 tmp = 0;
if (!unpack_u32(e, &tmp, NULL))
goto fail;
- profile->rules.rlimits.mask = tmp;
+ rules->rlimits.mask = tmp;
if (unpack_array(e, NULL, &size) != TRI_TRUE ||
size > RLIM_NLIMITS)
@@ -645,7 +644,7 @@ static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
int a = aa_map_resource(i);
if (!unpack_u64(e, &tmp2, NULL))
goto fail;
- profile->rules.rlimits.limits[a].rlim_max = tmp2;
+ rules->rlimits.limits[a].rlim_max = tmp2;
}
if (!unpack_nameX(e, AA_ARRAYEND, NULL))
goto fail;
@@ -852,7 +851,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
profile = aa_alloc_profile(name, NULL, GFP_KERNEL);
if (!profile)
return ERR_PTR(-ENOMEM);
- rules = &profile->rules;
+ rules = list_first_entry(&profile->rules, typeof(*rules), list);
/* profile renaming is optional */
(void) unpack_str(e, &profile->rename, "rename");
@@ -971,12 +970,12 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
goto fail;
}
- if (!unpack_rlimits(e, profile)) {
+ if (!unpack_rlimits(e, rules)) {
info = "failed to unpack profile rlimits";
goto fail;
}
- if (!unpack_secmark(e, profile)) {
+ if (!unpack_secmark(e, rules)) {
info = "failed to unpack profile secmark rules";
goto fail;
}
@@ -1208,23 +1207,26 @@ static bool verify_perms(struct aa_policydb *pdb)
*/
static int verify_profile(struct aa_profile *profile)
{
- if ((profile->rules.file.dfa &&
- !verify_dfa_xindex(profile->rules.file.dfa,
- profile->rules.file.trans.size)) ||
- (profile->rules.policy.dfa &&
- !verify_dfa_xindex(profile->rules.policy.dfa,
- profile->rules.policy.trans.size))) {
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
+ if (!rules)
+ return 0;
+
+ if ((rules->file.dfa && !verify_dfa_xindex(rules->file.dfa,
+ rules->file.trans.size)) ||
+ (rules->policy.dfa &&
+ !verify_dfa_xindex(rules->policy.dfa, rules->policy.trans.size))) {
audit_iface(profile, NULL, NULL,
"Unpack: Invalid named transition", NULL, -EPROTO);
return -EPROTO;
}
- if (!verify_perms(&profile->rules.file)) {
+ if (!verify_perms(&rules->file)) {
audit_iface(profile, NULL, NULL,
"Unpack: Invalid perm index", NULL, -EPROTO);
return -EPROTO;
}
- if (!verify_perms(&profile->rules.policy)) {
+ if (!verify_perms(&rules->policy)) {
audit_iface(profile, NULL, NULL,
"Unpack: Invalid perm index", NULL, -EPROTO);
return -EPROTO;
diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
index f28026804d13..ed543f4edfd9 100644
--- a/security/apparmor/resource.c
+++ b/security/apparmor/resource.c
@@ -82,7 +82,8 @@ int aa_map_resource(int resource)
static int profile_setrlimit(struct aa_profile *profile, unsigned int resource,
struct rlimit *new_rlim)
{
- struct aa_ruleset *rules = &profile->rules;
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
int e = 0;
if (rules->rlimits.mask & (1 << resource) && new_rlim->rlim_max >
@@ -154,12 +155,15 @@ void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l)
* to the lesser of the tasks hard limit and the init tasks soft limit
*/
label_for_each_confined(i, old_l, old) {
- if (old->rules.rlimits.mask) {
+ struct aa_ruleset *rules = list_first_entry(&old->rules,
+ typeof(*rules),
+ list);
+ if (rules->rlimits.mask) {
int j;
for (j = 0, mask = 1; j < RLIM_NLIMITS; j++,
mask <<= 1) {
- if (old->rules.rlimits.mask & mask) {
+ if (rules->rlimits.mask & mask) {
rlim = current->signal->rlim + j;
initrlim = init_task.signal->rlim + j;
rlim->rlim_cur = min(rlim->rlim_max,
@@ -171,17 +175,20 @@ void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l)
/* set any new hard limits as dictated by the new profile */
label_for_each_confined(i, new_l, new) {
+ struct aa_ruleset *rules = list_first_entry(&new->rules,
+ typeof(*rules),
+ list);
int j;
- if (!new->rules.rlimits.mask)
+ if (!rules->rlimits.mask)
continue;
for (j = 0, mask = 1; j < RLIM_NLIMITS; j++, mask <<= 1) {
- if (!(new->rules.rlimits.mask & mask))
+ if (!(rules->rlimits.mask & mask))
continue;
rlim = current->signal->rlim + j;
rlim->rlim_max = min(rlim->rlim_max,
- new->rules.rlimits.limits[j].rlim_max);
+ rules->rlimits.limits[j].rlim_max);
/* soft limit should not exceed hard limit */
rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max);
}
diff --git a/security/apparmor/task.c b/security/apparmor/task.c
index 7e64fba42ca3..5000cbd055b6 100644
--- a/security/apparmor/task.c
+++ b/security/apparmor/task.c
@@ -229,11 +229,13 @@ static int profile_ptrace_perm(struct aa_profile *profile,
struct aa_label *peer, u32 request,
struct common_audit_data *sa)
{
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
struct aa_perms perms = { };
aad(sa)->peer = peer;
- aa_profile_match_label(profile, &profile->rules, peer,
- AA_CLASS_PTRACE, request, &perms);
+ aa_profile_match_label(profile, rules, peer, AA_CLASS_PTRACE, request,
+ &perms);
aa_apply_modes_to_perms(profile, &perms);
return aa_check_perms(profile, &perms, request, sa, audit_ptrace_cb);
}
@@ -243,7 +245,7 @@ static int profile_tracee_perm(struct aa_profile *tracee,
struct common_audit_data *sa)
{
if (profile_unconfined(tracee) || unconfined(tracer) ||
- !RULE_MEDIATES(&tracee->rules, AA_CLASS_PTRACE))
+ !ANY_RULE_MEDIATES(&tracee->rules, AA_CLASS_PTRACE))
return 0;
return profile_ptrace_perm(tracee, tracer, request, sa);
@@ -256,7 +258,7 @@ static int profile_tracer_perm(struct aa_profile *tracer,
if (profile_unconfined(tracer))
return 0;
- if (RULE_MEDIATES(&tracer->rules, AA_CLASS_PTRACE))
+ if (ANY_RULE_MEDIATES(&tracer->rules, AA_CLASS_PTRACE))
return profile_ptrace_perm(tracer, tracee, request, sa);
/* profile uses the old style capability check for ptrace */