aboutsummaryrefslogtreecommitdiffstats
path: root/security/integrity/ima/ima_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/integrity/ima/ima_api.c')
-rw-r--r--security/integrity/ima/ima_api.c75
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
24static 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);
71out:
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;
77out_free: 54out:
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 }