Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9caafbe2 authored by Matthew Garrett's avatar Matthew Garrett Committed by John Johansen
Browse files

apparmor: Parse secmark policy



Add support for parsing secmark policy provided by userspace, and
store that in the overall policy.

Signed-off-by: default avatarMatthew Garrett <mjg59@google.com>
Signed-off-by: default avatarJohn Johansen <john.johansen@canonical.com>
parent 617a629c
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -83,6 +83,13 @@ struct aa_sk_ctx {
	__e;					\
})

struct aa_secmark {
	u8 audit;
	u8 deny;
	u32 secid;
	char *label;
};

extern struct aa_sfs_entry aa_sfs_entry_network[];

void audit_net_cb(struct audit_buffer *ab, void *va);
@@ -103,4 +110,7 @@ int aa_sk_perm(const char *op, u32 request, struct sock *sk);
int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
		      struct socket *sock);

int apparmor_secmark_check(struct aa_label *label, char *op, u32 request,
			   u32 secid, struct sock *sk);

#endif /* __AA_NET_H */
+3 −0
Original line number Diff line number Diff line
@@ -155,6 +155,9 @@ struct aa_profile {

	struct aa_rlimit rlimits;

	int secmark_count;
	struct aa_secmark *secmark;

	struct aa_loaddata *rawdata;
	unsigned char *hash;
	char *dirname;
+3 −0
Original line number Diff line number Diff line
@@ -231,6 +231,9 @@ void aa_free_profile(struct aa_profile *profile)
	for (i = 0; i < profile->xattr_count; i++)
		kzfree(profile->xattrs[i]);
	kzfree(profile->xattrs);
	for (i=0; i < profile->secmark_count; i++)
		kzfree(profile->secmark[i].label);
	kzfree(profile->secmark);
	kzfree(profile->dirname);
	aa_put_dfa(profile->xmatch);
	aa_put_dfa(profile->policy.dfa);
+61 −0
Original line number Diff line number Diff line
@@ -292,6 +292,19 @@ static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
	return 0;
}

static bool unpack_u8(struct aa_ext *e, u8 *data, const char *name)
{
	if (unpack_nameX(e, AA_U8, name)) {
		if (!inbounds(e, sizeof(u8)))
			return 0;
		if (data)
			*data = get_unaligned((u8 *)e->pos);
		e->pos += sizeof(u8);
		return 1;
	}
	return 0;
}

static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
{
	if (unpack_nameX(e, AA_U32, name)) {
@@ -529,6 +542,49 @@ static bool unpack_xattrs(struct aa_ext *e, struct aa_profile *profile)
	return 0;
}

static bool unpack_secmark(struct aa_ext *e, struct aa_profile *profile)
{
	void *pos = e->pos;
	int i, size;

	if (unpack_nameX(e, AA_STRUCT, "secmark")) {
		size = unpack_array(e, NULL);

		profile->secmark = kcalloc(size, sizeof(struct aa_secmark),
					   GFP_KERNEL);
		if (!profile->secmark)
			goto fail;

		profile->secmark_count = size;

		for (i = 0; i < size; i++) {
			if (!unpack_u8(e, &profile->secmark[i].audit, NULL))
				goto fail;
			if (!unpack_u8(e, &profile->secmark[i].deny, NULL))
				goto fail;
			if (!unpack_strdup(e, &profile->secmark[i].label, NULL))
				goto fail;
		}
		if (!unpack_nameX(e, AA_ARRAYEND, NULL))
			goto fail;
		if (!unpack_nameX(e, AA_STRUCTEND, NULL))
			goto fail;
	}

	return 1;

fail:
	if (profile->secmark) {
		for (i = 0; i < size; i++)
			kfree(profile->secmark[i].label);
		kfree(profile->secmark);
		profile->secmark_count = 0;
	}

	e->pos = pos;
	return 0;
}

static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
{
	void *pos = e->pos;
@@ -727,6 +783,11 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
		goto fail;
	}

	if (!unpack_secmark(e, profile)) {
		info = "failed to unpack profile secmark rules";
		goto fail;
	}

	if (unpack_nameX(e, AA_STRUCT, "policydb")) {
		/* generic policy dfa - optional and may be NULL */
		info = "failed to unpack policydb";