aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorRoberto Sassu <roberto.sassu@polito.it>2013-06-07 06:16:28 -0400
committerMimi Zohar <zohar@linux.vnet.ibm.com>2013-10-25 17:17:04 -0400
commit7bc5f447ce9d01e19394b5399bf1a4fcebf0f8dd (patch)
treeb15aaf6f56d81d204296455a80fd1ff29c4cd122 /security
parent9803d413f41db86fdf0097f1af781fe2e68f474c (diff)
ima: define new function ima_alloc_init_template() to API
Instead of allocating and initializing the template entry from multiple places (eg. boot aggregate, violation, and regular measurements), this patch defines a new function called ima_alloc_init_template(). The new function allocates and initializes the measurement entry with the inode digest and the filename. In respect to the current behavior, it truncates the file name passed in the 'filename' argument if the latter's size is greater than 255 bytes and the passed file descriptor is NULL. Changelog: - initialize 'hash' variable for non TPM case - Mimi - conform to expectation for 'iint' to be defined as a pointer. - Mimi - add missing 'file' dependency for recalculating file hash. - Mimi Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Diffstat (limited to 'security')
-rw-r--r--security/integrity/ima/ima.h3
-rw-r--r--security/integrity/ima/ima_api.c88
-rw-r--r--security/integrity/ima/ima_init.c24
3 files changed, 76 insertions, 39 deletions
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 27d2ffbd0763..da03d3389619 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -107,6 +107,9 @@ void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
107 const unsigned char *filename); 107 const unsigned char *filename);
108void ima_audit_measurement(struct integrity_iint_cache *iint, 108void ima_audit_measurement(struct integrity_iint_cache *iint,
109 const unsigned char *filename); 109 const unsigned char *filename);
110int ima_alloc_init_template(struct integrity_iint_cache *iint,
111 struct file *file, const unsigned char *filename,
112 struct ima_template_entry **entry);
110int ima_store_template(struct ima_template_entry *entry, int violation, 113int ima_store_template(struct ima_template_entry *entry, int violation,
111 struct inode *inode, const unsigned char *filename); 114 struct inode *inode, const unsigned char *filename);
112void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show); 115void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show);
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index a0fe5041310a..29dd43de823a 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -24,6 +24,62 @@
24static const char *IMA_TEMPLATE_NAME = "ima"; 24static const char *IMA_TEMPLATE_NAME = "ima";
25 25
26/* 26/*
27 * ima_alloc_init_template - create and initialize a new template entry
28 */
29int ima_alloc_init_template(struct integrity_iint_cache *iint,
30 struct file *file, const unsigned char *filename,
31 struct ima_template_entry **entry)
32{
33 struct ima_template_entry *e;
34 int result = 0;
35
36 e = kzalloc(sizeof(**entry), GFP_NOFS);
37 if (!e)
38 return -ENOMEM;
39
40 memset(&(e)->template, 0, sizeof(e->template));
41 if (!iint) /* IMA measurement violation entry */
42 goto out;
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
51 if (!file) {
52 result = -EINVAL;
53 goto out_free;
54 }
55
56 inode = file_inode(file);
57 hash.hdr.algo = ima_hash_algo;
58 hash.hdr.length = SHA1_DIGEST_SIZE;
59 result = ima_calc_file_hash(file, &hash.hdr);
60 if (result) {
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;
77out_free:
78 kfree(e);
79 return result;
80}
81
82/*
27 * ima_store_template - store ima template measurements 83 * ima_store_template - store ima template measurements
28 * 84 *
29 * Calculate the hash of a template entry, add the template entry 85 * Calculate the hash of a template entry, add the template entry
@@ -90,13 +146,11 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
90 /* can overflow, only indicator */ 146 /* can overflow, only indicator */
91 atomic_long_inc(&ima_htable.violations); 147 atomic_long_inc(&ima_htable.violations);
92 148
93 entry = kmalloc(sizeof(*entry), GFP_KERNEL); 149 result = ima_alloc_init_template(NULL, file, filename, &entry);
94 if (!entry) { 150 if (result < 0) {
95 result = -ENOMEM; 151 result = -ENOMEM;
96 goto err_out; 152 goto err_out;
97 } 153 }
98 memset(&entry->template, 0, sizeof(entry->template));
99 strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX);
100 result = ima_store_template(entry, violation, inode, filename); 154 result = ima_store_template(entry, violation, inode, filename);
101 if (result < 0) 155 if (result < 0)
102 kfree(entry); 156 kfree(entry);
@@ -220,34 +274,12 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
220 if (iint->flags & IMA_MEASURED) 274 if (iint->flags & IMA_MEASURED)
221 return; 275 return;
222 276
223 entry = kmalloc(sizeof(*entry), GFP_KERNEL); 277 result = ima_alloc_init_template(iint, file, filename, &entry);
224 if (!entry) { 278 if (result < 0) {
225 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, 279 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
226 op, audit_cause, result, 0); 280 op, audit_cause, result, 0);
227 return; 281 return;
228 } 282 }
229 memset(&entry->template, 0, sizeof(entry->template));
230 if (iint->ima_hash->algo != ima_hash_algo) {
231 struct {
232 struct ima_digest_data hdr;
233 char digest[IMA_MAX_DIGEST_SIZE];
234 } hash;
235
236 hash.hdr.algo = ima_hash_algo;
237 result = ima_calc_file_hash(file, &hash.hdr);
238 if (result)
239 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
240 filename, "collect_data", "failed",
241 result, 0);
242 else
243 memcpy(entry->template.digest, hash.hdr.digest,
244 hash.hdr.length);
245 } else
246 memcpy(entry->template.digest, iint->ima_hash->digest,
247 iint->ima_hash->length);
248 strcpy(entry->template.file_name,
249 (strlen(filename) > IMA_EVENT_NAME_LEN_MAX) ?
250 file->f_dentry->d_name.name : filename);
251 283
252 result = ima_store_template(entry, violation, inode, filename); 284 result = ima_store_template(entry, violation, inode, filename);
253 if (!result || result == -EEXIST) 285 if (!result || result == -EEXIST)
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index d42fac308aaa..50e15e6336c4 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -43,34 +43,36 @@ int ima_used_chip;
43static void __init ima_add_boot_aggregate(void) 43static void __init ima_add_boot_aggregate(void)
44{ 44{
45 struct ima_template_entry *entry; 45 struct ima_template_entry *entry;
46 struct integrity_iint_cache tmp_iint, *iint = &tmp_iint;
46 const char *op = "add_boot_aggregate"; 47 const char *op = "add_boot_aggregate";
47 const char *audit_cause = "ENOMEM"; 48 const char *audit_cause = "ENOMEM";
48 int result = -ENOMEM; 49 int result = -ENOMEM;
49 int violation = 1; 50 int violation = 0;
50 struct { 51 struct {
51 struct ima_digest_data hdr; 52 struct ima_digest_data hdr;
52 char digest[TPM_DIGEST_SIZE]; 53 char digest[TPM_DIGEST_SIZE];
53 } hash; 54 } hash;
54 55
55 entry = kmalloc(sizeof(*entry), GFP_KERNEL); 56 memset(iint, 0, sizeof(*iint));
56 if (!entry) 57 memset(&hash, 0, sizeof(hash));
57 goto err_out; 58 iint->ima_hash = &hash.hdr;
59 iint->ima_hash->algo = HASH_ALGO_SHA1;
60 iint->ima_hash->length = SHA1_DIGEST_SIZE;
58 61
59 memset(&entry->template, 0, sizeof(entry->template));
60 strncpy(entry->template.file_name, boot_aggregate_name,
61 IMA_EVENT_NAME_LEN_MAX);
62 if (ima_used_chip) { 62 if (ima_used_chip) {
63 violation = 0;
64 hash.hdr.algo = HASH_ALGO_SHA1;
65 result = ima_calc_boot_aggregate(&hash.hdr); 63 result = ima_calc_boot_aggregate(&hash.hdr);
66 if (result < 0) { 64 if (result < 0) {
67 audit_cause = "hashing_error"; 65 audit_cause = "hashing_error";
68 kfree(entry); 66 kfree(entry);
69 goto err_out; 67 goto err_out;
70 } 68 }
71 memcpy(entry->template.digest, hash.hdr.digest,
72 hash.hdr.length);
73 } 69 }
70
71 result = ima_alloc_init_template(iint, NULL, boot_aggregate_name,
72 &entry);
73 if (result < 0)
74 return;
75
74 result = ima_store_template(entry, violation, NULL, 76 result = ima_store_template(entry, violation, NULL,
75 boot_aggregate_name); 77 boot_aggregate_name);
76 if (result < 0) 78 if (result < 0)