apparmor: support querying extended trusted helper extra data
Allow a profile to carry extra data that can be queried via userspace. This provides a means to store extra data in a profile that a trusted helper can extract and use from live policy. Signed-off-by: William Hua <william.hua@canonical.com> Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:

committed by
John Johansen

parent
12eb87d50b
commit
e025be0f26
@@ -485,6 +485,30 @@ fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *kvmemdup(const void *src, size_t len)
|
||||
{
|
||||
void *p = kvmalloc(len);
|
||||
|
||||
if (p)
|
||||
memcpy(p, src, len);
|
||||
return p;
|
||||
}
|
||||
|
||||
static u32 strhash(const void *data, u32 len, u32 seed)
|
||||
{
|
||||
const char * const *key = data;
|
||||
|
||||
return jhash(*key, strlen(*key), seed);
|
||||
}
|
||||
|
||||
static int datacmp(struct rhashtable_compare_arg *arg, const void *obj)
|
||||
{
|
||||
const struct aa_data *data = obj;
|
||||
const char * const *key = arg->key;
|
||||
|
||||
return strcmp(data->key, *key);
|
||||
}
|
||||
|
||||
/**
|
||||
* unpack_profile - unpack a serialized profile
|
||||
* @e: serialized data extent information (NOT NULL)
|
||||
@@ -496,6 +520,9 @@ 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;
|
||||
size_t ns_len;
|
||||
struct rhashtable_params params = { 0 };
|
||||
char *key = NULL;
|
||||
struct aa_data *data;
|
||||
int i, error = -EPROTO;
|
||||
kernel_cap_t tmpcap;
|
||||
u32 tmp;
|
||||
@@ -654,6 +681,45 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
|
||||
if (!unpack_trans_table(e, profile))
|
||||
goto fail;
|
||||
|
||||
if (unpack_nameX(e, AA_STRUCT, "data")) {
|
||||
profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL);
|
||||
if (!profile->data)
|
||||
goto fail;
|
||||
|
||||
params.nelem_hint = 3;
|
||||
params.key_len = sizeof(void *);
|
||||
params.key_offset = offsetof(struct aa_data, key);
|
||||
params.head_offset = offsetof(struct aa_data, head);
|
||||
params.hashfn = strhash;
|
||||
params.obj_cmpfn = datacmp;
|
||||
|
||||
if (rhashtable_init(profile->data, ¶ms))
|
||||
goto fail;
|
||||
|
||||
while (unpack_strdup(e, &key, NULL)) {
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data) {
|
||||
kzfree(key);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
data->key = key;
|
||||
data->size = unpack_blob(e, &data->data, NULL);
|
||||
data->data = kvmemdup(data->data, data->size);
|
||||
if (data->size && !data->data) {
|
||||
kzfree(data->key);
|
||||
kzfree(data);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rhashtable_insert_fast(profile->data, &data->head,
|
||||
profile->data->p);
|
||||
}
|
||||
|
||||
if (!unpack_nameX(e, AA_STRUCTEND, NULL))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!unpack_nameX(e, AA_STRUCTEND, NULL))
|
||||
goto fail;
|
||||
|
||||
|
Reference in New Issue
Block a user