aboutsummaryrefslogtreecommitdiffstats
path: root/security/apparmor/policy_unpack.c
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2017-01-16 00:42:55 -0800
committerJohn Johansen <john.johansen@canonical.com>2017-01-16 01:18:42 -0800
commit5ac8c355ae0013d82b3a07b49aebeadfce9b6e52 (patch)
tree41f24f5f9198ef4ba7a34624938e51b2305e21f0 /security/apparmor/policy_unpack.c
parentapparmor: add ns name to the audit data for policy loads (diff)
downloadlinux-dev-5ac8c355ae0013d82b3a07b49aebeadfce9b6e52.tar.xz
linux-dev-5ac8c355ae0013d82b3a07b49aebeadfce9b6e52.zip
apparmor: allow introspecting the loaded policy pre internal transform
Store loaded policy and allow introspecting it through apparmorfs. This has several uses from debugging, policy validation, and policy checkpoint and restore for containers. Signed-off-by: John Johansen <john.johansen@canonical.com>
Diffstat (limited to 'security/apparmor/policy_unpack.c')
-rw-r--r--security/apparmor/policy_unpack.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index 51a7f9fc8a3e..fb4ef84b88e1 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -117,6 +117,16 @@ static int audit_iface(struct aa_profile *new, const char *name,
audit_cb);
}
+void aa_loaddata_kref(struct kref *kref)
+{
+ struct aa_loaddata *d = container_of(kref, struct aa_loaddata, count);
+
+ if (d) {
+ kzfree(d->hash);
+ kvfree(d);
+ }
+}
+
/* test if read will be in packed data bounds */
static bool inbounds(struct aa_ext *e, size_t size)
{
@@ -749,7 +759,6 @@ struct aa_load_ent *aa_load_ent_alloc(void)
/**
* aa_unpack - unpack packed binary profile(s) data loaded from user space
* @udata: user data copied to kmem (NOT NULL)
- * @size: the size of the user data
* @lh: list to place unpacked profiles in a aa_repl_ws
* @ns: Returns namespace profile is in if specified else NULL (NOT NULL)
*
@@ -759,15 +768,16 @@ struct aa_load_ent *aa_load_ent_alloc(void)
*
* Returns: profile(s) on @lh else error pointer if fails to unpack
*/
-int aa_unpack(void *udata, size_t size, struct list_head *lh, const char **ns)
+int aa_unpack(struct aa_loaddata *udata, struct list_head *lh,
+ const char **ns)
{
struct aa_load_ent *tmp, *ent;
struct aa_profile *profile = NULL;
int error;
struct aa_ext e = {
- .start = udata,
- .end = udata + size,
- .pos = udata,
+ .start = udata->data,
+ .end = udata->data + udata->size,
+ .pos = udata->data,
};
*ns = NULL;
@@ -802,7 +812,13 @@ int aa_unpack(void *udata, size_t size, struct list_head *lh, const char **ns)
ent->new = profile;
list_add_tail(&ent->list, lh);
}
-
+ udata->abi = e.version & K_ABI_MASK;
+ udata->hash = aa_calc_hash(udata->data, udata->size);
+ if (IS_ERR(udata->hash)) {
+ error = PTR_ERR(udata->hash);
+ udata->hash = NULL;
+ goto fail;
+ }
return 0;
fail_profile: