UBUNTU: SAUCE: apparmor4.0.0 [80/90]: apparmor: carry mediation check on label

BugLink: http://bugs.launchpad.net/bugs/2028253

In order to speed up the mediated check, precompute and store the
result as a bit per class type. This not only will allow us to
speed up the mediation check but is also a step to removing the
unconfined special cases as the unconfined check can be replaced
with the generic label_mediates() check.

need to compute initial profile mediated bit vector

Note: label check does not work for capabilities and resources

Signed-off-by: John Johansen <john.johansen@canonical.com>
(cherry picked from commit d8719977bc2bea2969846a49acfbabf06572ee1f
https://git.launchpad.net/~apparmor-dev/ubuntu-kernel-next)
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
This commit is contained in:
John Johansen
2023-10-27 10:31:06 -07:00
committed by Paolo Pisati
parent 4fff70a487
commit bd1e2a79d2
8 changed files with 70 additions and 29 deletions
+1 -1
View File
@@ -47,7 +47,7 @@ static inline int unix_fs_perm(const char *op, u32 mask,
AA_BUG(!u);
AA_BUG(!UNIX_FS(aa_unix_sk(u)));
if (unconfined(label) || !LABEL_MEDIATES(label, AA_CLASS_FILE))
if (unconfined(label) || !label_mediates(label, AA_CLASS_FILE))
return 0;
mask &= NET_FS_PERMS;
+1
View File
@@ -38,6 +38,7 @@
#define AA_CLASS_X 31
#define AA_CLASS_DBUS 32
/* NOTE: if AA_CLASS_LAST > 63 need to update label->mediates */
#define AA_CLASS_LAST AA_CLASS_DBUS
/* Control parameters settable through module/boot flags */
+11 -16
View File
@@ -129,6 +129,7 @@ struct aa_label {
long flags;
u32 secid;
int size;
u64 mediates;
struct aa_profile *vec[];
};
@@ -255,23 +256,17 @@ for ((I).i = (I).j = 0; \
#define fn_for_each_not_in_set(L1, L2, P, FN) \
fn_for_each2_XXX((L1), (L2), P, FN, _not_in_set)
#define LABEL_MEDIATES(L, C) \
({ \
struct aa_profile *profile; \
struct label_it i; \
int ret = 0; \
label_for_each(i, (L), profile) { \
struct aa_ruleset *rules = \
list_first_entry(&profile->rules, typeof(*rules),\
list); \
if (RULE_MEDIATES(rules, (C))) { \
ret = 1; \
break; \
} \
} \
ret; \
})
static inline bool label_mediates(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)
{
if (C > AA_CLASS_LAST)
return false;
return label_mediates(L, C);
}
int aa_label_cmp(struct aa_label *a, struct aa_label *b);
void aa_labelset_destroy(struct aa_labelset *ls);
+13
View File
@@ -334,6 +334,19 @@ static inline aa_state_t ANY_RULE_MEDIATES(struct list_head *head,
return RULE_MEDIATES(rule, class);
}
void aa_compute_profile_mediates(struct aa_profile *profile);
static inline bool profile_mediates(struct aa_profile *profile,
unsigned char class)
{
return label_mediates(&profile->label, class);
}
static inline bool profile_mediates_safe(struct aa_profile *profile,
unsigned char class)
{
return label_mediates_safe(&profile->label, class);
}
/**
* aa_get_profile - increment refcount on profile @p
* @p: profile (MAYBE NULL)
+14 -10
View File
@@ -198,21 +198,25 @@ static bool vec_is_stale(struct aa_profile **vec, int n)
return false;
}
static long accum_vec_flags(struct aa_profile **vec, int n)
static void accum_label_info(struct aa_label *new)
{
long u = FLAG_UNCONFINED;
int i;
AA_BUG(!vec);
AA_BUG(!new->vec);
for (i = 0; i < n; i++) {
u |= vec[i]->label.flags & (FLAG_DEBUG1 | FLAG_DEBUG2 |
FLAG_STALE);
if (!(u & vec[i]->label.flags & FLAG_UNCONFINED))
/* size == 1 is a profile and flags must be set as part of creation */
if (new->size == 1)
return;
for (i = 0; i < new->size; i++) {
u |= new->vec[i]->label.flags & (FLAG_DEBUG1 | FLAG_DEBUG2 |
FLAG_STALE);
if (!(u & new->vec[i]->label.flags & FLAG_UNCONFINED))
u &= ~FLAG_UNCONFINED;
new->mediates |= new->vec[i]->label.mediates;
}
return u;
new->flags |= u;
}
static int sort_cmp(const void *a, const void *b)
@@ -645,7 +649,7 @@ static bool __label_replace(struct aa_label *old, struct aa_label *new)
rb_replace_node(&old->node, &new->node, &ls->root);
old->flags &= ~FLAG_IN_TREE;
new->flags |= FLAG_IN_TREE;
new->flags |= accum_vec_flags(new->vec, new->size);
accum_label_info(new);
return true;
}
@@ -706,7 +710,7 @@ static struct aa_label *__label_insert(struct aa_labelset *ls,
rb_link_node(&label->node, parent, new);
rb_insert_color(&label->node, &ls->root);
label->flags |= FLAG_IN_TREE;
label->flags |= accum_vec_flags(label->vec, label->size);
accum_label_info(label);
return aa_get_label(label);
}
+1 -1
View File
@@ -1251,7 +1251,7 @@ static int apparmor_userns_create(const struct cred *cred)
label = begin_current_label_crit_section();
/* remove unprivileged_userns_restricted check when unconfined is updated */
if (aa_unprivileged_userns_restricted ||
LABEL_MEDIATES(label, AA_CLASS_NS)) {
label_mediates(label, AA_CLASS_NS)) {
DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_TASK, AA_CLASS_NS,
OP_USERNS_CREATE);
ad.subj_cred = current_cred();
+27 -1
View File
@@ -382,6 +382,30 @@ fail:
return NULL;
}
/* set of rules that are mediated by unconfined */
static int unconfined_mediates[] = { AA_CLASS_NS, AA_CLASS_IO_URING, 0 };
/* must be called after profile rulesets and start information is setup */
void aa_compute_profile_mediates(struct aa_profile *profile)
{
int c;
if (profile_unconfined(profile)) {
int *pos;
for (pos = unconfined_mediates; *pos; pos++) {
if (ANY_RULE_MEDIATES(&profile->rules, AA_CLASS_NS) !=
DFA_NOMATCH)
profile->label.mediates |= ((u64) 1) << AA_CLASS_NS;
}
return;
}
for (c = 0; c <= AA_CLASS_LAST; c++) {
if (ANY_RULE_MEDIATES(&profile->rules, c) != DFA_NOMATCH)
profile->label.mediates |= ((u64) 1) << c;
}
}
/* TODO: profile accounting - setup in remove */
/**
@@ -637,10 +661,12 @@ struct aa_profile *aa_alloc_null(struct aa_profile *parent, const char *name,
rules = list_first_entry(&profile->rules, typeof(*rules), list);
rules->file = aa_get_pdb(nullpdb);
rules->policy = aa_get_pdb(nullpdb);
aa_compute_profile_mediates(profile);
if (parent) {
profile->path_flags = parent->path_flags;
/* override/inherit what is mediated from parent */
profile->label.mediates = parent->label.mediates;
/* released on free_profile */
rcu_assign_pointer(profile->parent, aa_get_profile(parent));
profile->ns = aa_get_ns(parent->ns);
+2
View File
@@ -1144,6 +1144,8 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
goto fail;
}
aa_compute_profile_mediates(profile);
return profile;
fail: