Commit e2967ede authored by John Johansen's avatar John Johansen
Browse files

apparmor: compute policydb permission on profile load



Rather than computing policydb permissions for each access
permissions can be computed once on profile load and stored for lookup.

Signed-off-by: default avatarJohn Johansen <john.johansen@canonical.com>
parent e48ffd24
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -633,7 +633,7 @@ static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
		state = aa_dfa_match_len(dfa, profile->policy.start[0],
					 match_str, match_len);
		if (state)
			aa_compute_perms(dfa, state, &tmp);
			tmp = *aa_lookup_perms(profile->policy.perms, state);
	}
	aa_apply_modes_to_perms(profile, &tmp);
	aa_perms_accum_raw(perms, &tmp);
+11 −2
Original line number Diff line number Diff line
@@ -133,6 +133,17 @@ extern struct aa_perms allperms;
	xcheck(fn_for_each((L1), (P), (FN1)), fn_for_each((L2), (P), (FN2)))


extern struct aa_perms default_perms;

static inline struct aa_perms *aa_lookup_perms(struct aa_perms *perms,
					       unsigned int state)
{
	if (!(perms))
		return &default_perms;

	return &(perms[state]);
}

void aa_perm_mask_to_str(char *str, size_t str_size, const char *chrs,
			 u32 mask);
void aa_audit_perm_names(struct audit_buffer *ab, const char * const *names,
@@ -141,8 +152,6 @@ 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,
			     struct aa_perms *perms);
void aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
		      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, struct aa_label *label,
+1 −0
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ enum profile_mode {
struct aa_policydb {
	/* Generic policy DFA specific rule types will be subsections of it */
	struct aa_dfa *dfa;
	struct aa_perms *perms;
	unsigned int start[AA_CLASS_LAST + 1];

};
+3 −3
Original line number Diff line number Diff line
@@ -1328,7 +1328,7 @@ static int label_compound_match(struct aa_profile *profile,
		if (!state)
			goto fail;
	}
	aa_compute_perms(profile->policy.dfa, state, perms);
	*perms = *aa_lookup_perms(profile->policy.perms, state);
	aa_apply_modes_to_perms(profile, perms);
	if ((perms->allow & request) != request)
		return -EACCES;
@@ -1379,7 +1379,7 @@ static int label_components_match(struct aa_profile *profile,
	return 0;

next:
	aa_compute_perms(profile->policy.dfa, state, &tmp);
	tmp = *aa_lookup_perms(profile->policy.perms, state);
	aa_apply_modes_to_perms(profile, &tmp);
	aa_perms_accum(perms, &tmp);
	label_for_each_cont(i, label, tp) {
@@ -1388,7 +1388,7 @@ static int label_components_match(struct aa_profile *profile,
		state = match_component(profile, tp, start);
		if (!state)
			goto fail;
		aa_compute_perms(profile->policy.dfa, state, &tmp);
		tmp = *aa_lookup_perms(profile->policy.perms, state);
		aa_apply_modes_to_perms(profile, &tmp);
		aa_perms_accum(perms, &tmp);
	}
+0 −42
Original line number Diff line number Diff line
@@ -315,48 +315,6 @@ void aa_apply_modes_to_perms(struct aa_profile *profile, struct aa_perms *perms)
 */
}

static u32 map_other(u32 x)
{
	return ((x & 0x3) << 8) |	/* SETATTR/GETATTR */
		((x & 0x1c) << 18) |	/* ACCEPT/BIND/LISTEN */
		((x & 0x60) << 19);	/* SETOPT/GETOPT */
}

static u32 map_xbits(u32 x)
{
	return ((x & 0x1) << 7) |
		((x & 0x7e) << 9);
}

void aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
		      struct aa_perms *perms)
{
	/* This mapping is convulated due to history.
	 * v1-v4: only file perms
	 * v5: added policydb which dropped in perm user conditional to
	 *     gain new perm bits, but had to map around the xbits because
	 *     the userspace compiler was still munging them.
	 * v9: adds using the xbits in policydb because the compiler now
	 *     supports treating policydb permission bits different.
	 *     Unfortunately there is not way to force auditing on the
	 *     perms represented by the xbits
	 */
	*perms = (struct aa_perms) {
		.allow = dfa_user_allow(dfa, state) |
			 map_xbits(dfa_user_xbits(dfa, state)),
		.audit = dfa_user_audit(dfa, state),
		.quiet = dfa_user_quiet(dfa, state) |
			 map_xbits(dfa_other_xbits(dfa, state)),
	};

	/* for v5-v9 perm mapping in the policydb, the other set is used
	 * to extend the general perm set
	 */
	perms->allow |= map_other(dfa_other_allow(dfa, state));
	perms->audit |= map_other(dfa_other_audit(dfa, state));
	perms->quiet |= map_other(dfa_other_quiet(dfa, state));
}

/**
 * aa_perms_accum_raw - accumulate perms with out masking off overlapping perms
 * @accum - perms struct to accumulate into
Loading