mirror of
https://github.com/torvalds/linux
synced 2024-11-02 18:48:59 +00:00
apparmor: Parse secmark policy
Add support for parsing secmark policy provided by userspace, and store that in the overall policy. Signed-off-by: Matthew Garrett <mjg59@google.com> Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
parent
617a629c08
commit
9caafbe2b4
4 changed files with 77 additions and 0 deletions
|
@ -83,6 +83,13 @@ struct aa_sk_ctx {
|
||||||
__e; \
|
__e; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
struct aa_secmark {
|
||||||
|
u8 audit;
|
||||||
|
u8 deny;
|
||||||
|
u32 secid;
|
||||||
|
char *label;
|
||||||
|
};
|
||||||
|
|
||||||
extern struct aa_sfs_entry aa_sfs_entry_network[];
|
extern struct aa_sfs_entry aa_sfs_entry_network[];
|
||||||
|
|
||||||
void audit_net_cb(struct audit_buffer *ab, void *va);
|
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,
|
int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
|
||||||
struct socket *sock);
|
struct socket *sock);
|
||||||
|
|
||||||
|
int apparmor_secmark_check(struct aa_label *label, char *op, u32 request,
|
||||||
|
u32 secid, struct sock *sk);
|
||||||
|
|
||||||
#endif /* __AA_NET_H */
|
#endif /* __AA_NET_H */
|
||||||
|
|
|
@ -155,6 +155,9 @@ struct aa_profile {
|
||||||
|
|
||||||
struct aa_rlimit rlimits;
|
struct aa_rlimit rlimits;
|
||||||
|
|
||||||
|
int secmark_count;
|
||||||
|
struct aa_secmark *secmark;
|
||||||
|
|
||||||
struct aa_loaddata *rawdata;
|
struct aa_loaddata *rawdata;
|
||||||
unsigned char *hash;
|
unsigned char *hash;
|
||||||
char *dirname;
|
char *dirname;
|
||||||
|
|
|
@ -231,6 +231,9 @@ void aa_free_profile(struct aa_profile *profile)
|
||||||
for (i = 0; i < profile->xattr_count; i++)
|
for (i = 0; i < profile->xattr_count; i++)
|
||||||
kzfree(profile->xattrs[i]);
|
kzfree(profile->xattrs[i]);
|
||||||
kzfree(profile->xattrs);
|
kzfree(profile->xattrs);
|
||||||
|
for (i=0; i < profile->secmark_count; i++)
|
||||||
|
kzfree(profile->secmark[i].label);
|
||||||
|
kzfree(profile->secmark);
|
||||||
kzfree(profile->dirname);
|
kzfree(profile->dirname);
|
||||||
aa_put_dfa(profile->xmatch);
|
aa_put_dfa(profile->xmatch);
|
||||||
aa_put_dfa(profile->policy.dfa);
|
aa_put_dfa(profile->policy.dfa);
|
||||||
|
|
|
@ -292,6 +292,19 @@ static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
|
||||||
return 0;
|
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)
|
static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
|
||||||
{
|
{
|
||||||
if (unpack_nameX(e, AA_U32, 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;
|
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)
|
static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
|
||||||
{
|
{
|
||||||
void *pos = e->pos;
|
void *pos = e->pos;
|
||||||
|
@ -727,6 +783,11 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!unpack_secmark(e, profile)) {
|
||||||
|
info = "failed to unpack profile secmark rules";
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
if (unpack_nameX(e, AA_STRUCT, "policydb")) {
|
if (unpack_nameX(e, AA_STRUCT, "policydb")) {
|
||||||
/* generic policy dfa - optional and may be NULL */
|
/* generic policy dfa - optional and may be NULL */
|
||||||
info = "failed to unpack policydb";
|
info = "failed to unpack policydb";
|
||||||
|
|
Loading…
Reference in a new issue