summaryrefslogtreecommitdiff
path: root/security/apparmor/policy_unpack.c
diff options
context:
space:
mode:
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: