Commit 23b57419 authored by Roberto Sassu's avatar Roberto Sassu Committed by Mimi Zohar

ima: wrap event related data to the new ima_event_data structure

All event related data has been wrapped into the new 'ima_event_data'
structure. The main benefit of this patch is that a new information
can be made available to template fields initialization functions
by simply adding a new field to the new structure instead of modifying
the definition of those functions.

Changelog:
 - v2:
   - f_dentry replaced with f_path.dentry (Roberto Sassu)
   - removed declaration of temporary variables in template field functions
     when possible (suggested by Dmitry Kasatkin)
Signed-off-by: default avatarRoberto Sassu <rsassu@suse.de>
Signed-off-by: default avatarMimi Zohar <zohar@linux.vnet.ibm.com>
parent 9d03a721
...@@ -52,6 +52,15 @@ extern int ima_used_chip; ...@@ -52,6 +52,15 @@ extern int ima_used_chip;
extern int ima_hash_algo; extern int ima_hash_algo;
extern int ima_appraise; extern int ima_appraise;
/* IMA event related data */
struct ima_event_data {
struct integrity_iint_cache *iint;
struct file *file;
const unsigned char *filename;
struct evm_ima_xattr_data *xattr_value;
int xattr_len;
};
/* IMA template field data definition */ /* IMA template field data definition */
struct ima_field_data { struct ima_field_data {
u8 *data; u8 *data;
...@@ -61,11 +70,9 @@ struct ima_field_data { ...@@ -61,11 +70,9 @@ struct ima_field_data {
/* IMA template field definition */ /* IMA template field definition */
struct ima_template_field { struct ima_template_field {
const char field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN]; const char field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN];
int (*field_init) (struct integrity_iint_cache *iint, struct file *file, int (*field_init)(struct ima_event_data *event_data,
const unsigned char *filename, struct ima_field_data *field_data);
struct evm_ima_xattr_data *xattr_value, void (*field_show)(struct seq_file *m, enum ima_show_type show,
int xattr_len, struct ima_field_data *field_data);
void (*field_show) (struct seq_file *m, enum ima_show_type show,
struct ima_field_data *field_data); struct ima_field_data *field_data);
}; };
...@@ -140,10 +147,8 @@ void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, ...@@ -140,10 +147,8 @@ void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
int xattr_len); int xattr_len);
void ima_audit_measurement(struct integrity_iint_cache *iint, void ima_audit_measurement(struct integrity_iint_cache *iint,
const unsigned char *filename); const unsigned char *filename);
int ima_alloc_init_template(struct integrity_iint_cache *iint, int ima_alloc_init_template(struct ima_event_data *event_data,
struct file *file, const unsigned char *filename, struct ima_template_entry **entry);
struct evm_ima_xattr_data *xattr_value,
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); void ima_free_template_entry(struct ima_template_entry *entry);
......
...@@ -37,10 +37,8 @@ void ima_free_template_entry(struct ima_template_entry *entry) ...@@ -37,10 +37,8 @@ void ima_free_template_entry(struct ima_template_entry *entry)
/* /*
* ima_alloc_init_template - create and initialize a new template entry * ima_alloc_init_template - create and initialize a new template entry
*/ */
int ima_alloc_init_template(struct integrity_iint_cache *iint, int ima_alloc_init_template(struct ima_event_data *event_data,
struct file *file, const unsigned char *filename, struct ima_template_entry **entry)
struct evm_ima_xattr_data *xattr_value,
int xattr_len, struct ima_template_entry **entry)
{ {
struct ima_template_desc *template_desc = ima_template_desc_current(); struct ima_template_desc *template_desc = ima_template_desc_current();
int i, result = 0; int i, result = 0;
...@@ -55,8 +53,7 @@ int ima_alloc_init_template(struct integrity_iint_cache *iint, ...@@ -55,8 +53,7 @@ int ima_alloc_init_template(struct integrity_iint_cache *iint,
struct ima_template_field *field = template_desc->fields[i]; struct ima_template_field *field = template_desc->fields[i];
u32 len; u32 len;
result = field->field_init(iint, file, filename, result = field->field_init(event_data,
xattr_value, xattr_len,
&((*entry)->template_data[i])); &((*entry)->template_data[i]));
if (result != 0) if (result != 0)
goto out; goto out;
...@@ -133,14 +130,14 @@ void ima_add_violation(struct file *file, const unsigned char *filename, ...@@ -133,14 +130,14 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
{ {
struct ima_template_entry *entry; struct ima_template_entry *entry;
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
struct ima_event_data event_data = {NULL, file, filename, NULL, 0};
int violation = 1; int violation = 1;
int result; int result;
/* can overflow, only indicator */ /* can overflow, only indicator */
atomic_long_inc(&ima_htable.violations); atomic_long_inc(&ima_htable.violations);
result = ima_alloc_init_template(NULL, file, filename, result = ima_alloc_init_template(&event_data, &entry);
NULL, 0, &entry);
if (result < 0) { if (result < 0) {
result = -ENOMEM; result = -ENOMEM;
goto err_out; goto err_out;
...@@ -267,13 +264,14 @@ void ima_store_measurement(struct integrity_iint_cache *iint, ...@@ -267,13 +264,14 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
int result = -ENOMEM; int result = -ENOMEM;
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
struct ima_template_entry *entry; struct ima_template_entry *entry;
struct ima_event_data event_data = {iint, file, filename,
xattr_value, xattr_len};
int violation = 0; int violation = 0;
if (iint->flags & IMA_MEASURED) if (iint->flags & IMA_MEASURED)
return; return;
result = ima_alloc_init_template(iint, file, filename, result = ima_alloc_init_template(&event_data, &entry);
xattr_value, xattr_len, &entry);
if (result < 0) { if (result < 0) {
integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
op, audit_cause, result, 0); op, audit_cause, result, 0);
......
...@@ -49,6 +49,8 @@ static int __init ima_add_boot_aggregate(void) ...@@ -49,6 +49,8 @@ static int __init ima_add_boot_aggregate(void)
const char *audit_cause = "ENOMEM"; const char *audit_cause = "ENOMEM";
struct ima_template_entry *entry; struct ima_template_entry *entry;
struct integrity_iint_cache tmp_iint, *iint = &tmp_iint; struct integrity_iint_cache tmp_iint, *iint = &tmp_iint;
struct ima_event_data event_data = {iint, NULL, boot_aggregate_name,
NULL, 0};
int result = -ENOMEM; int result = -ENOMEM;
int violation = 0; int violation = 0;
struct { struct {
...@@ -70,8 +72,7 @@ static int __init ima_add_boot_aggregate(void) ...@@ -70,8 +72,7 @@ static int __init ima_add_boot_aggregate(void)
} }
} }
result = ima_alloc_init_template(iint, NULL, boot_aggregate_name, result = ima_alloc_init_template(&event_data, &entry);
NULL, 0, &entry);
if (result < 0) { if (result < 0) {
audit_cause = "alloc_entry"; audit_cause = "alloc_entry";
goto err_out; goto err_out;
......
...@@ -195,9 +195,7 @@ static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo, ...@@ -195,9 +195,7 @@ static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo,
/* /*
* This function writes the digest of an event (with size limit). * This function writes the digest of an event (with size limit).
*/ */
int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file, int ima_eventdigest_init(struct ima_event_data *event_data,
const unsigned char *filename,
struct evm_ima_xattr_data *xattr_value, int xattr_len,
struct ima_field_data *field_data) struct ima_field_data *field_data)
{ {
struct { struct {
...@@ -211,25 +209,25 @@ int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file, ...@@ -211,25 +209,25 @@ int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
memset(&hash, 0, sizeof(hash)); memset(&hash, 0, sizeof(hash));
if (!iint) /* recording a violation. */ if (!event_data->iint) /* recording a violation. */
goto out; goto out;
if (ima_template_hash_algo_allowed(iint->ima_hash->algo)) { if (ima_template_hash_algo_allowed(event_data->iint->ima_hash->algo)) {
cur_digest = iint->ima_hash->digest; cur_digest = event_data->iint->ima_hash->digest;
cur_digestsize = iint->ima_hash->length; cur_digestsize = event_data->iint->ima_hash->length;
goto out; goto out;
} }
if (!file) /* missing info to re-calculate the digest */ if (!event_data->file) /* missing info to re-calculate the digest */
return -EINVAL; return -EINVAL;
inode = file_inode(file); inode = file_inode(event_data->file);
hash.hdr.algo = ima_template_hash_algo_allowed(ima_hash_algo) ? hash.hdr.algo = ima_template_hash_algo_allowed(ima_hash_algo) ?
ima_hash_algo : HASH_ALGO_SHA1; ima_hash_algo : HASH_ALGO_SHA1;
result = ima_calc_file_hash(file, &hash.hdr); result = ima_calc_file_hash(event_data->file, &hash.hdr);
if (result) { if (result) {
integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
filename, "collect_data", event_data->filename, "collect_data",
"failed", result, 0); "failed", result, 0);
return result; return result;
} }
...@@ -243,48 +241,44 @@ int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file, ...@@ -243,48 +241,44 @@ int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
/* /*
* This function writes the digest of an event (without size limit). * This function writes the digest of an event (without size limit).
*/ */
int ima_eventdigest_ng_init(struct integrity_iint_cache *iint, int ima_eventdigest_ng_init(struct ima_event_data *event_data,
struct file *file, const unsigned char *filename, struct ima_field_data *field_data)
struct evm_ima_xattr_data *xattr_value,
int xattr_len, struct ima_field_data *field_data)
{ {
u8 *cur_digest = NULL, hash_algo = HASH_ALGO_SHA1; u8 *cur_digest = NULL, hash_algo = HASH_ALGO_SHA1;
u32 cur_digestsize = 0; u32 cur_digestsize = 0;
/* If iint is NULL, we are recording a violation. */ /* If iint is NULL, we are recording a violation. */
if (!iint) if (!event_data->iint)
goto out; goto out;
cur_digest = iint->ima_hash->digest; cur_digest = event_data->iint->ima_hash->digest;
cur_digestsize = iint->ima_hash->length; cur_digestsize = event_data->iint->ima_hash->length;
hash_algo = iint->ima_hash->algo; hash_algo = event_data->iint->ima_hash->algo;
out: out:
return ima_eventdigest_init_common(cur_digest, cur_digestsize, return ima_eventdigest_init_common(cur_digest, cur_digestsize,
hash_algo, field_data); hash_algo, field_data);
} }
static int ima_eventname_init_common(struct integrity_iint_cache *iint, static int ima_eventname_init_common(struct ima_event_data *event_data,
struct file *file,
const unsigned char *filename,
struct ima_field_data *field_data, struct ima_field_data *field_data,
bool size_limit) bool size_limit)
{ {
const char *cur_filename = NULL; const char *cur_filename = NULL;
u32 cur_filename_len = 0; u32 cur_filename_len = 0;
BUG_ON(filename == NULL && file == NULL); BUG_ON(event_data->filename == NULL && event_data->file == NULL);
if (filename) { if (event_data->filename) {
cur_filename = filename; cur_filename = event_data->filename;
cur_filename_len = strlen(filename); cur_filename_len = strlen(event_data->filename);
if (!size_limit || cur_filename_len <= IMA_EVENT_NAME_LEN_MAX) if (!size_limit || cur_filename_len <= IMA_EVENT_NAME_LEN_MAX)
goto out; goto out;
} }
if (file) { if (event_data->file) {
cur_filename = file->f_path.dentry->d_name.name; cur_filename = event_data->file->f_path.dentry->d_name.name;
cur_filename_len = strlen(cur_filename); cur_filename_len = strlen(cur_filename);
} else } else
/* /*
...@@ -300,36 +294,30 @@ static int ima_eventname_init_common(struct integrity_iint_cache *iint, ...@@ -300,36 +294,30 @@ static int ima_eventname_init_common(struct integrity_iint_cache *iint,
/* /*
* This function writes the name of an event (with size limit). * This function writes the name of an event (with size limit).
*/ */
int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file, int ima_eventname_init(struct ima_event_data *event_data,
const unsigned char *filename,
struct evm_ima_xattr_data *xattr_value, int xattr_len,
struct ima_field_data *field_data) struct ima_field_data *field_data)
{ {
return ima_eventname_init_common(iint, file, filename, return ima_eventname_init_common(event_data, field_data, true);
field_data, true);
} }
/* /*
* This function writes the name of an event (without size limit). * This function writes the name of an event (without size limit).
*/ */
int ima_eventname_ng_init(struct integrity_iint_cache *iint, struct file *file, int ima_eventname_ng_init(struct ima_event_data *event_data,
const unsigned char *filename,
struct evm_ima_xattr_data *xattr_value, int xattr_len,
struct ima_field_data *field_data) struct ima_field_data *field_data)
{ {
return ima_eventname_init_common(iint, file, filename, return ima_eventname_init_common(event_data, field_data, false);
field_data, false);
} }
/* /*
* ima_eventsig_init - include the file signature as part of the template data * ima_eventsig_init - include the file signature as part of the template data
*/ */
int ima_eventsig_init(struct integrity_iint_cache *iint, struct file *file, int ima_eventsig_init(struct ima_event_data *event_data,
const unsigned char *filename,
struct evm_ima_xattr_data *xattr_value, int xattr_len,
struct ima_field_data *field_data) struct ima_field_data *field_data)
{ {
enum data_formats fmt = DATA_FMT_HEX; enum data_formats fmt = DATA_FMT_HEX;
struct evm_ima_xattr_data *xattr_value = event_data->xattr_value;
int xattr_len = event_data->xattr_len;
int rc = 0; int rc = 0;
if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG)) if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG))
......
...@@ -26,24 +26,14 @@ void ima_show_template_string(struct seq_file *m, enum ima_show_type show, ...@@ -26,24 +26,14 @@ void ima_show_template_string(struct seq_file *m, enum ima_show_type show,
struct ima_field_data *field_data); struct ima_field_data *field_data);
void ima_show_template_sig(struct seq_file *m, enum ima_show_type show, void ima_show_template_sig(struct seq_file *m, enum ima_show_type show,
struct ima_field_data *field_data); struct ima_field_data *field_data);
int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file, int ima_eventdigest_init(struct ima_event_data *event_data,
const unsigned char *filename, struct ima_field_data *field_data);
struct evm_ima_xattr_data *xattr_value, int xattr_len, int ima_eventname_init(struct ima_event_data *event_data,
struct ima_field_data *field_data); struct ima_field_data *field_data);
int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file, int ima_eventdigest_ng_init(struct ima_event_data *event_data,
const unsigned char *filename, struct ima_field_data *field_data);
struct evm_ima_xattr_data *xattr_value, int xattr_len, int ima_eventname_ng_init(struct ima_event_data *event_data,
struct ima_field_data *field_data); struct ima_field_data *field_data);
int ima_eventdigest_ng_init(struct integrity_iint_cache *iint, int ima_eventsig_init(struct ima_event_data *event_data,
struct file *file, const unsigned char *filename,
struct evm_ima_xattr_data *xattr_value,
int xattr_len, struct ima_field_data *field_data);
int ima_eventname_ng_init(struct integrity_iint_cache *iint, struct file *file,
const unsigned char *filename,
struct evm_ima_xattr_data *xattr_value, int xattr_len,
struct ima_field_data *field_data);
int ima_eventsig_init(struct integrity_iint_cache *iint, struct file *file,
const unsigned char *filename,
struct evm_ima_xattr_data *xattr_value, int xattr_len,
struct ima_field_data *field_data); struct ima_field_data *field_data);
#endif /* __LINUX_IMA_TEMPLATE_LIB_H */ #endif /* __LINUX_IMA_TEMPLATE_LIB_H */
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