diff options
| -rw-r--r-- | security/integrity/ima/ima.h | 19 | ||||
| -rw-r--r-- | security/integrity/ima/ima_api.c | 75 | ||||
| -rw-r--r-- | security/integrity/ima/ima_crypto.c | 34 | ||||
| -rw-r--r-- | security/integrity/ima/ima_fs.c | 54 | ||||
| -rw-r--r-- | security/integrity/ima/ima_template.c | 22 |
5 files changed, 107 insertions, 97 deletions
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index e1f081d65dbf..72d013e190b1 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h | |||
| @@ -72,17 +72,11 @@ struct ima_template_desc { | |||
| 72 | struct ima_template_field **fields; | 72 | struct ima_template_field **fields; |
| 73 | }; | 73 | }; |
| 74 | 74 | ||
| 75 | /* IMA inode template definition */ | ||
| 76 | struct ima_template_data { | ||
| 77 | u8 digest[IMA_DIGEST_SIZE]; /* sha1/md5 measurement hash */ | ||
| 78 | char file_name[IMA_EVENT_NAME_LEN_MAX + 1]; /* name + \0 */ | ||
| 79 | }; | ||
| 80 | |||
| 81 | struct ima_template_entry { | 75 | struct ima_template_entry { |
| 82 | u8 digest[TPM_DIGEST_SIZE]; /* sha1 or md5 measurement hash */ | 76 | u8 digest[TPM_DIGEST_SIZE]; /* sha1 or md5 measurement hash */ |
| 83 | const char *template_name; | 77 | struct ima_template_desc *template_desc; /* template descriptor */ |
| 84 | int template_len; | 78 | u32 template_data_len; |
| 85 | struct ima_template_data template; | 79 | struct ima_field_data template_data[0]; /* template related data */ |
| 86 | }; | 80 | }; |
| 87 | 81 | ||
| 88 | struct ima_queue_entry { | 82 | struct ima_queue_entry { |
| @@ -102,14 +96,16 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation, | |||
| 102 | const char *op, struct inode *inode, | 96 | const char *op, struct inode *inode, |
| 103 | const unsigned char *filename); | 97 | const unsigned char *filename); |
| 104 | int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash); | 98 | int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash); |
| 105 | int ima_calc_buffer_hash(const void *data, int len, | 99 | int ima_calc_field_array_hash(struct ima_field_data *field_data, int num_fields, |
| 106 | struct ima_digest_data *hash); | 100 | struct ima_digest_data *hash); |
| 107 | int __init ima_calc_boot_aggregate(struct ima_digest_data *hash); | 101 | int __init ima_calc_boot_aggregate(struct ima_digest_data *hash); |
| 108 | void ima_add_violation(struct file *file, const unsigned char *filename, | 102 | void ima_add_violation(struct file *file, const unsigned char *filename, |
| 109 | const char *op, const char *cause); | 103 | const char *op, const char *cause); |
| 110 | int ima_init_crypto(void); | 104 | int ima_init_crypto(void); |
| 111 | void ima_putc(struct seq_file *m, void *data, int datalen); | 105 | void ima_putc(struct seq_file *m, void *data, int datalen); |
| 112 | void ima_print_digest(struct seq_file *m, u8 *digest, int size); | 106 | void ima_print_digest(struct seq_file *m, u8 *digest, int size); |
| 107 | struct ima_template_desc *ima_template_desc_current(void); | ||
| 108 | int ima_init_template(void); | ||
| 113 | 109 | ||
| 114 | int ima_init_template(void); | 110 | int ima_init_template(void); |
| 115 | 111 | ||
| @@ -146,7 +142,6 @@ int ima_alloc_init_template(struct integrity_iint_cache *iint, | |||
| 146 | struct ima_template_entry **entry); | 142 | struct ima_template_entry **entry); |
| 147 | int ima_store_template(struct ima_template_entry *entry, int violation, | 143 | int ima_store_template(struct ima_template_entry *entry, int violation, |
| 148 | struct inode *inode, const unsigned char *filename); | 144 | struct inode *inode, const unsigned char *filename); |
| 149 | void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show); | ||
| 150 | const char *ima_d_path(struct path *path, char **pathbuf); | 145 | const char *ima_d_path(struct path *path, char **pathbuf); |
| 151 | 146 | ||
| 152 | /* rbtree tree calls to lookup, insert, delete | 147 | /* rbtree tree calls to lookup, insert, delete |
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index 29dd43de823a..baa348179527 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c | |||
| @@ -21,8 +21,6 @@ | |||
| 21 | #include <crypto/hash_info.h> | 21 | #include <crypto/hash_info.h> |
| 22 | #include "ima.h" | 22 | #include "ima.h" |
| 23 | 23 | ||
| 24 | static const char *IMA_TEMPLATE_NAME = "ima"; | ||
| 25 | |||
| 26 | /* | 24 | /* |
| 27 | * ima_alloc_init_template - create and initialize a new template entry | 25 | * ima_alloc_init_template - create and initialize a new template entry |
| 28 | */ | 26 | */ |
| @@ -30,52 +28,32 @@ int ima_alloc_init_template(struct integrity_iint_cache *iint, | |||
| 30 | struct file *file, const unsigned char *filename, | 28 | struct file *file, const unsigned char *filename, |
| 31 | struct ima_template_entry **entry) | 29 | struct ima_template_entry **entry) |
| 32 | { | 30 | { |
| 33 | struct ima_template_entry *e; | 31 | struct ima_template_desc *template_desc = ima_template_desc_current(); |
| 34 | int result = 0; | 32 | int i, result = 0; |
| 35 | 33 | ||
| 36 | e = kzalloc(sizeof(**entry), GFP_NOFS); | 34 | *entry = kzalloc(sizeof(**entry) + template_desc->num_fields * |
| 37 | if (!e) | 35 | sizeof(struct ima_field_data), GFP_NOFS); |
| 36 | if (!*entry) | ||
| 38 | return -ENOMEM; | 37 | return -ENOMEM; |
| 39 | 38 | ||
| 40 | memset(&(e)->template, 0, sizeof(e->template)); | 39 | for (i = 0; i < template_desc->num_fields; i++) { |
| 41 | if (!iint) /* IMA measurement violation entry */ | 40 | struct ima_template_field *field = template_desc->fields[i]; |
| 42 | goto out; | 41 | u32 len; |
| 43 | |||
| 44 | if (iint->ima_hash->algo != ima_hash_algo) { | ||
| 45 | struct inode *inode; | ||
| 46 | struct { | ||
| 47 | struct ima_digest_data hdr; | ||
| 48 | char digest[IMA_MAX_DIGEST_SIZE]; | ||
| 49 | } hash; | ||
| 50 | 42 | ||
| 51 | if (!file) { | 43 | result = field->field_init(iint, file, filename, |
| 52 | result = -EINVAL; | 44 | &((*entry)->template_data[i])); |
| 53 | goto out_free; | 45 | if (result != 0) |
| 54 | } | 46 | goto out; |
| 55 | 47 | ||
| 56 | inode = file_inode(file); | 48 | len = (*entry)->template_data[i].len; |
| 57 | hash.hdr.algo = ima_hash_algo; | 49 | (*entry)->template_data_len += sizeof(len); |
| 58 | hash.hdr.length = SHA1_DIGEST_SIZE; | 50 | (*entry)->template_data_len += len; |
| 59 | result = ima_calc_file_hash(file, &hash.hdr); | 51 | } |
| 60 | if (result) { | 52 | (*entry)->template_desc = template_desc; |
| 61 | integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, | ||
| 62 | filename, "collect_data", | ||
| 63 | "failed", result, 0); | ||
| 64 | goto out_free; | ||
| 65 | } else | ||
| 66 | memcpy(e->template.digest, hash.hdr.digest, | ||
| 67 | hash.hdr.length); | ||
| 68 | } else | ||
| 69 | memcpy(e->template.digest, iint->ima_hash->digest, | ||
| 70 | iint->ima_hash->length); | ||
| 71 | out: | ||
| 72 | strcpy(e->template.file_name, | ||
| 73 | (strlen(filename) > IMA_EVENT_NAME_LEN_MAX && file != NULL) ? | ||
| 74 | file->f_dentry->d_name.name : filename); | ||
| 75 | *entry = e; | ||
| 76 | return 0; | 53 | return 0; |
| 77 | out_free: | 54 | out: |
| 78 | kfree(e); | 55 | kfree(*entry); |
| 56 | *entry = NULL; | ||
| 79 | return result; | 57 | return result; |
| 80 | } | 58 | } |
| 81 | 59 | ||
| @@ -101,24 +79,23 @@ int ima_store_template(struct ima_template_entry *entry, | |||
| 101 | { | 79 | { |
| 102 | const char *op = "add_template_measure"; | 80 | const char *op = "add_template_measure"; |
| 103 | const char *audit_cause = "hashing_error"; | 81 | const char *audit_cause = "hashing_error"; |
| 82 | char *template_name = entry->template_desc->name; | ||
| 104 | int result; | 83 | int result; |
| 105 | struct { | 84 | struct { |
| 106 | struct ima_digest_data hdr; | 85 | struct ima_digest_data hdr; |
| 107 | char digest[TPM_DIGEST_SIZE]; | 86 | char digest[TPM_DIGEST_SIZE]; |
| 108 | } hash; | 87 | } hash; |
| 109 | 88 | ||
| 110 | memset(entry->digest, 0, sizeof(entry->digest)); | ||
| 111 | entry->template_name = IMA_TEMPLATE_NAME; | ||
| 112 | entry->template_len = sizeof(entry->template); | ||
| 113 | |||
| 114 | if (!violation) { | 89 | if (!violation) { |
| 90 | int num_fields = entry->template_desc->num_fields; | ||
| 91 | |||
| 115 | /* this function uses default algo */ | 92 | /* this function uses default algo */ |
| 116 | hash.hdr.algo = HASH_ALGO_SHA1; | 93 | hash.hdr.algo = HASH_ALGO_SHA1; |
| 117 | result = ima_calc_buffer_hash(&entry->template, | 94 | result = ima_calc_field_array_hash(&entry->template_data[0], |
| 118 | entry->template_len, &hash.hdr); | 95 | num_fields, &hash.hdr); |
| 119 | if (result < 0) { | 96 | if (result < 0) { |
| 120 | integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, | 97 | integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, |
| 121 | entry->template_name, op, | 98 | template_name, op, |
| 122 | audit_cause, result, 0); | ||
