mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 16:35:02 +01:00

The old out of tree patchseries has been completely dropped. v4.13 has most of the newer apparmor 3.x code in it. v4.14 has the rest except the af_unix mediation which is included as the last patch
219 lines
7.3 KiB
Diff
219 lines
7.3 KiB
Diff
From aa4b6bded85552bc5f9f22d2e18ce86c5c17947c Mon Sep 17 00:00:00 2001
|
|
From: John Johansen <john.johansen@canonical.com>
|
|
Date: Tue, 18 Jul 2017 23:37:18 -0700
|
|
Subject: [PATCH 10/17] apparmor: make policy_unpack able to audit different
|
|
info messages
|
|
|
|
Switch unpack auditing to using the generic name field in the audit
|
|
struct and make it so we can start adding new info messages about
|
|
why an unpack failed.
|
|
|
|
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
|
Acked-by: Seth Arnold <seth.arnold@canonical.com>
|
|
(cherry picked from commit 1489d896c5649e9ce1b6000b4857f8baa7a6ab63)
|
|
---
|
|
security/apparmor/include/audit.h | 4 +--
|
|
security/apparmor/policy_unpack.c | 52 ++++++++++++++++++++++++++++-----------
|
|
2 files changed, 40 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
|
|
index c3fe1c5ef3bc..620e81169659 100644
|
|
--- a/security/apparmor/include/audit.h
|
|
+++ b/security/apparmor/include/audit.h
|
|
@@ -127,9 +127,9 @@ struct apparmor_audit_data {
|
|
} fs;
|
|
};
|
|
struct {
|
|
- const char *name;
|
|
- long pos;
|
|
+ struct aa_profile *profile;
|
|
const char *ns;
|
|
+ long pos;
|
|
} iface;
|
|
int signal;
|
|
struct {
|
|
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
|
|
index bda0dce3b582..4ede87c30f8b 100644
|
|
--- a/security/apparmor/policy_unpack.c
|
|
+++ b/security/apparmor/policy_unpack.c
|
|
@@ -85,9 +85,9 @@ static void audit_cb(struct audit_buffer *ab, void *va)
|
|
audit_log_format(ab, " ns=");
|
|
audit_log_untrustedstring(ab, aad(sa)->iface.ns);
|
|
}
|
|
- if (aad(sa)->iface.name) {
|
|
+ if (aad(sa)->name) {
|
|
audit_log_format(ab, " name=");
|
|
- audit_log_untrustedstring(ab, aad(sa)->iface.name);
|
|
+ audit_log_untrustedstring(ab, aad(sa)->name);
|
|
}
|
|
if (aad(sa)->iface.pos)
|
|
audit_log_format(ab, " offset=%ld", aad(sa)->iface.pos);
|
|
@@ -114,9 +114,9 @@ static int audit_iface(struct aa_profile *new, const char *ns_name,
|
|
aad(&sa)->iface.pos = e->pos - e->start;
|
|
aad(&sa)->iface.ns = ns_name;
|
|
if (new)
|
|
- aad(&sa)->iface.name = new->base.hname;
|
|
+ aad(&sa)->name = new->base.hname;
|
|
else
|
|
- aad(&sa)->iface.name = name;
|
|
+ aad(&sa)->name = name;
|
|
aad(&sa)->info = info;
|
|
aad(&sa)->error = error;
|
|
|
|
@@ -583,6 +583,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
|
|
{
|
|
struct aa_profile *profile = NULL;
|
|
const char *tmpname, *tmpns = NULL, *name = NULL;
|
|
+ const char *info = "failed to unpack profile";
|
|
size_t ns_len;
|
|
struct rhashtable_params params = { 0 };
|
|
char *key = NULL;
|
|
@@ -604,8 +605,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
|
|
tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len);
|
|
if (tmpns) {
|
|
*ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL);
|
|
- if (!*ns_name)
|
|
+ if (!*ns_name) {
|
|
+ info = "out of memory";
|
|
goto fail;
|
|
+ }
|
|
name = tmpname;
|
|
}
|
|
|
|
@@ -624,12 +627,15 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
|
|
if (IS_ERR(profile->xmatch)) {
|
|
error = PTR_ERR(profile->xmatch);
|
|
profile->xmatch = NULL;
|
|
+ info = "bad xmatch";
|
|
goto fail;
|
|
}
|
|
/* xmatch_len is not optional if xmatch is set */
|
|
if (profile->xmatch) {
|
|
- if (!unpack_u32(e, &tmp, NULL))
|
|
+ if (!unpack_u32(e, &tmp, NULL)) {
|
|
+ info = "missing xmatch len";
|
|
goto fail;
|
|
+ }
|
|
profile->xmatch_len = tmp;
|
|
}
|
|
|
|
@@ -637,8 +643,11 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
|
|
(void) unpack_str(e, &profile->disconnected, "disconnected");
|
|
|
|
/* per profile debug flags (complain, audit) */
|
|
- if (!unpack_nameX(e, AA_STRUCT, "flags"))
|
|
+ if (!unpack_nameX(e, AA_STRUCT, "flags")) {
|
|
+ info = "profile missing flags";
|
|
goto fail;
|
|
+ }
|
|
+ info = "failed to unpack profile flags";
|
|
if (!unpack_u32(e, &tmp, NULL))
|
|
goto fail;
|
|
if (tmp & PACKED_FLAG_HAT)
|
|
@@ -667,6 +676,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
|
|
/* set a default value if path_flags field is not present */
|
|
profile->path_flags = PATH_MEDIATE_DELETED;
|
|
|
|
+ info = "failed to unpack profile capabilities";
|
|
if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL))
|
|
goto fail;
|
|
if (!unpack_u32(e, &(profile->caps.audit.cap[0]), NULL))
|
|
@@ -676,6 +686,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
|
|
if (!unpack_u32(e, &tmpcap.cap[0], NULL))
|
|
goto fail;
|
|
|
|
+ info = "failed to unpack upper profile capabilities";
|
|
if (unpack_nameX(e, AA_STRUCT, "caps64")) {
|
|
/* optional upper half of 64 bit caps */
|
|
if (!unpack_u32(e, &(profile->caps.allow.cap[1]), NULL))
|
|
@@ -690,6 +701,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
|
|
goto fail;
|
|
}
|
|
|
|
+ info = "failed to unpack extended profile capabilities";
|
|
if (unpack_nameX(e, AA_STRUCT, "capsx")) {
|
|
/* optional extended caps mediation mask */
|
|
if (!unpack_u32(e, &(profile->caps.extended.cap[0]), NULL))
|
|
@@ -700,11 +712,14 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
|
|
goto fail;
|
|
}
|
|
|
|
- if (!unpack_rlimits(e, profile))
|
|
+ if (!unpack_rlimits(e, profile)) {
|
|
+ info = "failed to unpack profile rlimits";
|
|
goto fail;
|
|
+ }
|
|
|
|
if (unpack_nameX(e, AA_STRUCT, "policydb")) {
|
|
/* generic policy dfa - optional and may be NULL */
|
|
+ info = "failed to unpack policydb";
|
|
profile->policy.dfa = unpack_dfa(e);
|
|
if (IS_ERR(profile->policy.dfa)) {
|
|
error = PTR_ERR(profile->policy.dfa);
|
|
@@ -734,6 +749,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
|
|
if (IS_ERR(profile->file.dfa)) {
|
|
error = PTR_ERR(profile->file.dfa);
|
|
profile->file.dfa = NULL;
|
|
+ info = "failed to unpack profile file rules";
|
|
goto fail;
|
|
} else if (profile->file.dfa) {
|
|
if (!unpack_u32(e, &profile->file.start, "dfa_start"))
|
|
@@ -746,10 +762,13 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
|
|
} else
|
|
profile->file.dfa = aa_get_dfa(nulldfa);
|
|
|
|
- if (!unpack_trans_table(e, profile))
|
|
+ if (!unpack_trans_table(e, profile)) {
|
|
+ info = "failed to unpack profile transition table";
|
|
goto fail;
|
|
+ }
|
|
|
|
if (unpack_nameX(e, AA_STRUCT, "data")) {
|
|
+ info = "out of memory";
|
|
profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL);
|
|
if (!profile->data)
|
|
goto fail;
|
|
@@ -761,8 +780,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
|
|
params.hashfn = strhash;
|
|
params.obj_cmpfn = datacmp;
|
|
|
|
- if (rhashtable_init(profile->data, ¶ms))
|
|
+ if (rhashtable_init(profile->data, ¶ms)) {
|
|
+ info = "failed to init key, value hash table";
|
|
goto fail;
|
|
+ }
|
|
|
|
while (unpack_strdup(e, &key, NULL)) {
|
|
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
|
@@ -784,12 +805,16 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
|
|
profile->data->p);
|
|
}
|
|
|
|
- if (!unpack_nameX(e, AA_STRUCTEND, NULL))
|
|
+ if (!unpack_nameX(e, AA_STRUCTEND, NULL)) {
|
|
+ info = "failed to unpack end of key, value data table";
|
|
goto fail;
|
|
+ }
|
|
}
|
|
|
|
- if (!unpack_nameX(e, AA_STRUCTEND, NULL))
|
|
+ if (!unpack_nameX(e, AA_STRUCTEND, NULL)) {
|
|
+ info = "failed to unpack end of profile";
|
|
goto fail;
|
|
+ }
|
|
|
|
return profile;
|
|
|
|
@@ -798,8 +823,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
|
|
name = NULL;
|
|
else if (!name)
|
|
name = "unknown";
|
|
- audit_iface(profile, NULL, name, "failed to unpack profile", e,
|
|
- error);
|
|
+ audit_iface(profile, NULL, name, info, e, error);
|
|
aa_free_profile(profile);
|
|
|
|
return ERR_PTR(error);
|
|
--
|
|
2.11.0
|
|
|