ima: wrap event related data to the new ima_event_data structure
authorRoberto Sassu <rsassu@suse.de>
Sat, 11 Apr 2015 15:09:50 +0000 (17:09 +0200)
committerMimi Zohar <zohar@linux.vnet.ibm.com>
Thu, 21 May 2015 17:59:28 +0000 (13:59 -0400)
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: Roberto Sassu <rsassu@suse.de>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
security/integrity/ima/ima.h
security/integrity/ima/ima_api.c
security/integrity/ima/ima_init.c
security/integrity/ima/ima_template_lib.c
security/integrity/ima/ima_template_lib.h

index 8ee997d..e13ae54 100644 (file)
@@ -52,6 +52,15 @@ extern int ima_used_chip;
 extern int ima_hash_algo;
 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 */
 struct ima_field_data {
        u8 *data;
@@ -61,12 +70,10 @@ struct ima_field_data {
 /* IMA template field definition */
 struct ima_template_field {
        const char field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN];
-       int (*field_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);
-       void (*field_show) (struct seq_file *m, enum ima_show_type show,
-                           struct ima_field_data *field_data);
+       int (*field_init)(struct ima_event_data *event_data,
+                         struct ima_field_data *field_data);
+       void (*field_show)(struct seq_file *m, enum ima_show_type show,
+                          struct ima_field_data *field_data);
 };
 
 /* IMA template descriptor definition */
@@ -140,10 +147,8 @@ void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
                           int xattr_len);
 void ima_audit_measurement(struct integrity_iint_cache *iint,
                           const unsigned char *filename);
-int ima_alloc_init_template(struct integrity_iint_cache *iint,
-                           struct file *file, const unsigned char *filename,
-                           struct evm_ima_xattr_data *xattr_value,
-                           int xattr_len, struct ima_template_entry **entry);
+int ima_alloc_init_template(struct ima_event_data *event_data,
+                           struct ima_template_entry **entry);
 int ima_store_template(struct ima_template_entry *entry, int violation,
                       struct inode *inode, const unsigned char *filename);
 void ima_free_template_entry(struct ima_template_entry *entry);
index b8a27c5..5865ea2 100644 (file)
@@ -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
  */
-int ima_alloc_init_template(struct integrity_iint_cache *iint,
-                           struct file *file, const unsigned char *filename,
-                           struct evm_ima_xattr_data *xattr_value,
-                           int xattr_len, struct ima_template_entry **entry)
+int ima_alloc_init_template(struct ima_event_data *event_data,
+                           struct ima_template_entry **entry)
 {
        struct ima_template_desc *template_desc = ima_template_desc_current();
        int i, result = 0;
@@ -55,8 +53,7 @@ int ima_alloc_init_template(struct integrity_iint_cache *iint,
                struct ima_template_field *field = template_desc->fields[i];
                u32 len;
 
-               result = field->field_init(iint, file, filename,
-                                          xattr_value, xattr_len,
+               result = field->field_init(event_data,
                                           &((*entry)->template_data[i]));
                if (result != 0)
                        goto out;
@@ -133,14 +130,14 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
 {
        struct ima_template_entry *entry;
        struct inode *inode = file_inode(file);
+       struct ima_event_data event_data = {NULL, file, filename, NULL, 0};
        int violation = 1;
        int result;
 
        /* can overflow, only indicator */
        atomic_long_inc(&ima_htable.violations);
 
-       result = ima_alloc_init_template(NULL, file, filename,
-                                        NULL, 0, &entry);
+       result = ima_alloc_init_template(&event_data, &entry);
        if (result < 0) {
                result = -ENOMEM;
                goto err_out;
@@ -267,13 +264,14 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
        int result = -ENOMEM;
        struct inode *inode = file_inode(file);
        struct ima_template_entry *entry;
+       struct ima_event_data event_data = {iint, file, filename,
+                                           xattr_value, xattr_len};
        int violation = 0;
 
        if (iint->flags & IMA_MEASURED)
                return;
 
-       result = ima_alloc_init_template(iint, file, filename,
-                                        xattr_value, xattr_len, &entry);
+       result = ima_alloc_init_template(&event_data, &entry);
        if (result < 0) {
                integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
                                    op, audit_cause, result, 0);
index 0f4cffd..2c66837 100644 (file)
@@ -49,6 +49,8 @@ static int __init ima_add_boot_aggregate(void)
        const char *audit_cause = "ENOMEM";
        struct ima_template_entry *entry;
        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 violation = 0;
        struct {
@@ -70,8 +72,7 @@ static int __init ima_add_boot_aggregate(void)
                }
        }
 
-       result = ima_alloc_init_template(iint, NULL, boot_aggregate_name,
-                                        NULL, 0, &entry);
+       result = ima_alloc_init_template(&event_data, &entry);
        if (result < 0) {
                audit_cause = "alloc_entry";
                goto err_out;
index bcfc36c..67d5133 100644 (file)
@@ -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).
  */
-int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
-                        const unsigned char *filename,
-                        struct evm_ima_xattr_data *xattr_value, int xattr_len,
+int ima_eventdigest_init(struct ima_event_data *event_data,
                         struct ima_field_data *field_data)
 {
        struct {
@@ -211,25 +209,25 @@ int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
 
        memset(&hash, 0, sizeof(hash));
 
-       if (!iint)              /* recording a violation. */
+       if (!event_data->iint)          /* recording a violation. */
                goto out;
 
-       if (ima_template_hash_algo_allowed(iint->ima_hash->algo)) {
-               cur_digest = iint->ima_hash->digest;
-               cur_digestsize = iint->ima_hash->length;
+       if (ima_template_hash_algo_allowed(event_data->iint->ima_hash->algo)) {
+               cur_digest = event_data->iint->ima_hash->digest;
+               cur_digestsize = event_data->iint->ima_hash->length;
                goto out;
        }
 
-       if (!file)              /* missing info to re-calculate the digest */
+       if (!event_data->file)  /* missing info to re-calculate the digest */
                return -EINVAL;
 
-       inode = file_inode(file);
+       inode = file_inode(event_data->file);
        hash.hdr.algo = ima_template_hash_algo_allowed(ima_hash_algo) ?
            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) {
                integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
-                                   filename, "collect_data",
+                                   event_data->filename, "collect_data",
                                    "failed", result, 0);
                return result;
        }
@@ -243,48 +241,44 @@ out:
 /*
  * This function writes the digest of an event (without size limit).
  */
-int ima_eventdigest_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_eventdigest_ng_init(struct ima_event_data *event_data,
+                           struct ima_field_data *field_data)
 {
        u8 *cur_digest = NULL, hash_algo = HASH_ALGO_SHA1;
        u32 cur_digestsize = 0;
 
        /* If iint is NULL, we are recording a violation. */
-       if (!iint)
+       if (!event_data->iint)
                goto out;
 
-       cur_digest = iint->ima_hash->digest;
-       cur_digestsize = iint->ima_hash->length;
+       cur_digest = event_data->iint->ima_hash->digest;
+       cur_digestsize = event_data->iint->ima_hash->length;
 
-       hash_algo = iint->ima_hash->algo;
+       hash_algo = event_data->iint->ima_hash->algo;
 out:
        return ima_eventdigest_init_common(cur_digest, cur_digestsize,
                                           hash_algo, field_data);
 }
 
-static int ima_eventname_init_common(struct integrity_iint_cache *iint,
-                                    struct file *file,
-                                    const unsigned char *filename,
+static int ima_eventname_init_common(struct ima_event_data *event_data,
                                     struct ima_field_data *field_data,
                                     bool size_limit)
 {
        const char *cur_filename = NULL;
        u32 cur_filename_len = 0;
 
-       BUG_ON(filename == NULL && file == NULL);
+       BUG_ON(event_data->filename == NULL && event_data->file == NULL);
 
-       if (filename) {
-               cur_filename = filename;
-               cur_filename_len = strlen(filename);
+       if (event_data->filename) {
+               cur_filename = event_data->filename;
+               cur_filename_len = strlen(event_data->filename);
 
                if (!size_limit || cur_filename_len <= IMA_EVENT_NAME_LEN_MAX)
                        goto out;
        }
 
-       if (file) {
-               cur_filename = file->f_path.dentry->d_name.name;
+       if (event_data->file) {
+               cur_filename = event_data->file->f_path.dentry->d_name.name;
                cur_filename_len = strlen(cur_filename);
        } else
                /*
@@ -300,36 +294,30 @@ out:
 /*
  * This function writes the name of an event (with size limit).
  */
-int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file,
-                      const unsigned char *filename,
-                      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)
 {
-       return ima_eventname_init_common(iint, file, filename,
-                                        field_data, true);
+       return ima_eventname_init_common(event_data, field_data, true);
 }
 
 /*
  * This function writes the name of an event (without size limit).
  */
-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,
+int ima_eventname_ng_init(struct ima_event_data *event_data,
                          struct ima_field_data *field_data)
 {
-       return ima_eventname_init_common(iint, file, filename,
-                                        field_data, false);
+       return ima_eventname_init_common(event_data, field_data, false);
 }
 
 /*
  *  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,
-                     const unsigned char *filename,
-                     struct evm_ima_xattr_data *xattr_value, int xattr_len,
+int ima_eventsig_init(struct ima_event_data *event_data,
                      struct ima_field_data *field_data)
 {
        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;
 
        if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG))
index 63f6b52..c344530 100644 (file)
@@ -26,24 +26,14 @@ void ima_show_template_string(struct seq_file *m, enum ima_show_type show,
                              struct ima_field_data *field_data);
 void ima_show_template_sig(struct seq_file *m, enum ima_show_type show,
                           struct ima_field_data *field_data);
-int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
-                        const unsigned char *filename,
-                        struct evm_ima_xattr_data *xattr_value, int xattr_len,
+int ima_eventdigest_init(struct ima_event_data *event_data,
                         struct ima_field_data *field_data);
-int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file,
-                      const unsigned char *filename,
-                      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);
-int ima_eventdigest_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_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,
+int ima_eventdigest_ng_init(struct ima_event_data *event_data,
+                           struct ima_field_data *field_data);
+int ima_eventname_ng_init(struct ima_event_data *event_data,
                          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,
+int ima_eventsig_init(struct ima_event_data *event_data,
                      struct ima_field_data *field_data);
 #endif /* __LINUX_IMA_TEMPLATE_LIB_H */