diff options
Diffstat (limited to 'security/integrity/ima/ima_api.c')
-rw-r--r-- | security/integrity/ima/ima_api.c | 75 |
1 files changed, 26 insertions, 49 deletions
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); | 99 | audit_cause, result, 0); |
123 | return result; | 100 | return result; |
124 | } | 101 | } |