Commit a7ed7c60 authored by Roberto Sassu's avatar Roberto Sassu Committed by Mimi Zohar

ima: properly free ima_template_entry structures

The new templates management mechanism records information associated
to an event into an array of 'ima_field_data' structures and makes it
available through the 'template_data' field of the 'ima_template_entry'
structure (the element of the measurements list created by IMA).

Since 'ima_field_data' contains dynamically allocated data (which length
varies depending on the data associated to a selected template field),
it is not enough to just free the memory reserved for a
'ima_template_entry' structure if something goes wrong.

This patch creates the new function ima_free_template_entry() which
walks the array of 'ima_field_data' structures, frees the memory
referenced by the 'data' pointer and finally the space reserved for
the 'ima_template_entry' structure. Further, it replaces existing kfree()
that have a pointer to an 'ima_template_entry' structure as argument
with calls to the new function.

Fixes: a71dc65d: ima: switch to new template management mechanism
Signed-off-by: default avatarRoberto Sassu <roberto.sassu@polito.it>
Signed-off-by: default avatarMimi Zohar <zohar@us.ibm.com>
parent 09ae6345
...@@ -148,6 +148,7 @@ int ima_alloc_init_template(struct integrity_iint_cache *iint, ...@@ -148,6 +148,7 @@ int ima_alloc_init_template(struct integrity_iint_cache *iint,
int xattr_len, struct ima_template_entry **entry); int xattr_len, struct ima_template_entry **entry);
int ima_store_template(struct ima_template_entry *entry, int violation, int ima_store_template(struct ima_template_entry *entry, int violation,
struct inode *inode, const unsigned char *filename); struct inode *inode, const unsigned char *filename);
void ima_free_template_entry(struct ima_template_entry *entry);
const char *ima_d_path(struct path *path, char **pathbuf); const char *ima_d_path(struct path *path, char **pathbuf);
/* rbtree tree calls to lookup, insert, delete /* rbtree tree calls to lookup, insert, delete
......
...@@ -21,6 +21,19 @@ ...@@ -21,6 +21,19 @@
#include <crypto/hash_info.h> #include <crypto/hash_info.h>
#include "ima.h" #include "ima.h"
/*
* ima_free_template_entry - free an existing template entry
*/
void ima_free_template_entry(struct ima_template_entry *entry)
{
int i;
for (i = 0; i < entry->template_desc->num_fields; i++)
kfree(entry->template_data[i].data);
kfree(entry);
}
/* /*
* ima_alloc_init_template - create and initialize a new template entry * ima_alloc_init_template - create and initialize a new template entry
*/ */
...@@ -37,6 +50,7 @@ int ima_alloc_init_template(struct integrity_iint_cache *iint, ...@@ -37,6 +50,7 @@ int ima_alloc_init_template(struct integrity_iint_cache *iint,
if (!*entry) if (!*entry)
return -ENOMEM; return -ENOMEM;
(*entry)->template_desc = template_desc;
for (i = 0; i < template_desc->num_fields; i++) { for (i = 0; i < template_desc->num_fields; i++) {
struct ima_template_field *field = template_desc->fields[i]; struct ima_template_field *field = template_desc->fields[i];
u32 len; u32 len;
...@@ -51,10 +65,9 @@ int ima_alloc_init_template(struct integrity_iint_cache *iint, ...@@ -51,10 +65,9 @@ int ima_alloc_init_template(struct integrity_iint_cache *iint,
(*entry)->template_data_len += sizeof(len); (*entry)->template_data_len += sizeof(len);
(*entry)->template_data_len += len; (*entry)->template_data_len += len;
} }
(*entry)->template_desc = template_desc;
return 0; return 0;
out: out:
kfree(*entry); ima_free_template_entry(*entry);
*entry = NULL; *entry = NULL;
return result; return result;
} }
...@@ -134,7 +147,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename, ...@@ -134,7 +147,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
} }
result = ima_store_template(entry, violation, inode, filename); result = ima_store_template(entry, violation, inode, filename);
if (result < 0) if (result < 0)
kfree(entry); ima_free_template_entry(entry);
err_out: err_out:
integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
op, cause, result, 0); op, cause, result, 0);
...@@ -269,7 +282,7 @@ void ima_store_measurement(struct integrity_iint_cache *iint, ...@@ -269,7 +282,7 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
if (!result || result == -EEXIST) if (!result || result == -EEXIST)
iint->flags |= IMA_MEASURED; iint->flags |= IMA_MEASURED;
if (result < 0) if (result < 0)
kfree(entry); ima_free_template_entry(entry);
} }
void ima_audit_measurement(struct integrity_iint_cache *iint, void ima_audit_measurement(struct integrity_iint_cache *iint,
......
...@@ -75,7 +75,7 @@ static void __init ima_add_boot_aggregate(void) ...@@ -75,7 +75,7 @@ static void __init ima_add_boot_aggregate(void)
result = ima_store_template(entry, violation, NULL, result = ima_store_template(entry, violation, NULL,
boot_aggregate_name); boot_aggregate_name);
if (result < 0) if (result < 0)
kfree(entry); ima_free_template_entry(entry);
return; return;
err_out: err_out:
integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, boot_aggregate_name, op, integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, boot_aggregate_name, op,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment