aboutsummaryrefslogtreecommitdiffstats
path: root/security/integrity/ima
diff options
context:
space:
mode:
Diffstat (limited to 'security/integrity/ima')
-rw-r--r--security/integrity/ima/Kconfig64
-rw-r--r--security/integrity/ima/Makefile2
-rw-r--r--security/integrity/ima/ima.h106
-rw-r--r--security/integrity/ima/ima_api.c154
-rw-r--r--security/integrity/ima/ima_appraise.c106
-rw-r--r--security/integrity/ima/ima_crypto.c141
-rw-r--r--security/integrity/ima/ima_fs.c75
-rw-r--r--security/integrity/ima/ima_init.c40
-rw-r--r--security/integrity/ima/ima_main.c63
-rw-r--r--security/integrity/ima/ima_policy.c1
-rw-r--r--security/integrity/ima/ima_queue.c10
-rw-r--r--security/integrity/ima/ima_template.c187
-rw-r--r--security/integrity/ima/ima_template_lib.c351
-rw-r--r--security/integrity/ima/ima_template_lib.h49
14 files changed, 1185 insertions, 164 deletions
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 39196abaff0d..81a27971d884 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -9,6 +9,7 @@ config IMA
9 select CRYPTO_HMAC 9 select CRYPTO_HMAC
10 select CRYPTO_MD5 10 select CRYPTO_MD5
11 select CRYPTO_SHA1 11 select CRYPTO_SHA1
12 select CRYPTO_HASH_INFO
12 select TCG_TPM if HAS_IOMEM && !UML 13 select TCG_TPM if HAS_IOMEM && !UML
13 select TCG_TIS if TCG_TPM && X86 14 select TCG_TIS if TCG_TPM && X86
14 select TCG_IBMVTPM if TCG_TPM && PPC64 15 select TCG_IBMVTPM if TCG_TPM && PPC64
@@ -45,6 +46,69 @@ config IMA_LSM_RULES
45 help 46 help
46 Disabling this option will disregard LSM based policy rules. 47 Disabling this option will disregard LSM based policy rules.
47 48
49choice
50 prompt "Default template"
51 default IMA_NG_TEMPLATE
52 depends on IMA
53 help
54 Select the default IMA measurement template.
55
56 The original 'ima' measurement list template contains a
57 hash, defined as 20 bytes, and a null terminated pathname,
58 limited to 255 characters. The 'ima-ng' measurement list
59 template permits both larger hash digests and longer
60 pathnames.
61
62 config IMA_TEMPLATE
63 bool "ima"
64 config IMA_NG_TEMPLATE
65 bool "ima-ng (default)"
66 config IMA_SIG_TEMPLATE
67 bool "ima-sig"
68endchoice
69
70config IMA_DEFAULT_TEMPLATE
71 string
72 depends on IMA
73 default "ima" if IMA_TEMPLATE
74 default "ima-ng" if IMA_NG_TEMPLATE
75 default "ima-sig" if IMA_SIG_TEMPLATE
76
77choice
78 prompt "Default integrity hash algorithm"
79 default IMA_DEFAULT_HASH_SHA1
80 depends on IMA
81 help
82 Select the default hash algorithm used for the measurement
83 list, integrity appraisal and audit log. The compiled default
84 hash algorithm can be overwritten using the kernel command
85 line 'ima_hash=' option.
86
87 config IMA_DEFAULT_HASH_SHA1
88 bool "SHA1 (default)"
89 depends on CRYPTO_SHA1
90
91 config IMA_DEFAULT_HASH_SHA256
92 bool "SHA256"
93 depends on CRYPTO_SHA256 && !IMA_TEMPLATE
94
95 config IMA_DEFAULT_HASH_SHA512
96 bool "SHA512"
97 depends on CRYPTO_SHA512 && !IMA_TEMPLATE
98
99 config IMA_DEFAULT_HASH_WP512
100 bool "WP512"
101 depends on CRYPTO_WP512 && !IMA_TEMPLATE
102endchoice
103
104config IMA_DEFAULT_HASH
105 string
106 depends on IMA
107 default "sha1" if IMA_DEFAULT_HASH_SHA1
108 default "sha256" if IMA_DEFAULT_HASH_SHA256
109 default "sha512" if IMA_DEFAULT_HASH_SHA512
110 default "wp512" if IMA_DEFAULT_HASH_WP512
111
48config IMA_APPRAISE 112config IMA_APPRAISE
49 bool "Appraise integrity measurements" 113 bool "Appraise integrity measurements"
50 depends on IMA 114 depends on IMA
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index 56dfee7cbf61..d79263d2fdbf 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -6,5 +6,5 @@
6obj-$(CONFIG_IMA) += ima.o 6obj-$(CONFIG_IMA) += ima.o
7 7
8ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ 8ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
9 ima_policy.o 9 ima_policy.o ima_template.o ima_template_lib.o
10ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o 10ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index b3dd616560f7..0356e1d437ca 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -26,7 +26,8 @@
26 26
27#include "../integrity.h" 27#include "../integrity.h"
28 28
29enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII }; 29enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_BINARY_NO_FIELD_LEN,
30 IMA_SHOW_ASCII };
30enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; 31enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
31 32
32/* digest size for IMA, fits SHA1 or MD5 */ 33/* digest size for IMA, fits SHA1 or MD5 */
@@ -36,23 +37,48 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
36#define IMA_HASH_BITS 9 37#define IMA_HASH_BITS 9
37#define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS) 38#define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS)
38 39
40#define IMA_TEMPLATE_FIELD_ID_MAX_LEN 16
41#define IMA_TEMPLATE_NUM_FIELDS_MAX 15
42
43#define IMA_TEMPLATE_IMA_NAME "ima"
44#define IMA_TEMPLATE_IMA_FMT "d|n"
45
39/* set during initialization */ 46/* set during initialization */
40extern int ima_initialized; 47extern int ima_initialized;
41extern int ima_used_chip; 48extern int ima_used_chip;
42extern char *ima_hash; 49extern int ima_hash_algo;
43extern int ima_appraise; 50extern int ima_appraise;
44 51
45/* IMA inode template definition */ 52/* IMA template field data definition */
46struct ima_template_data { 53struct ima_field_data {
47 u8 digest[IMA_DIGEST_SIZE]; /* sha1/md5 measurement hash */ 54 u8 *data;
48 char file_name[IMA_EVENT_NAME_LEN_MAX + 1]; /* name + \0 */ 55 u32 len;
56};
57
58/* IMA template field definition */
59struct ima_template_field {
60 const char field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN];
61 int (*field_init) (struct integrity_iint_cache *iint, struct file *file,
62 const unsigned char *filename,
63 struct evm_ima_xattr_data *xattr_value,
64 int xattr_len, struct ima_field_data *field_data);
65 void (*field_show) (struct seq_file *m, enum ima_show_type show,
66 struct ima_field_data *field_data);
67};
68
69/* IMA template descriptor definition */
70struct ima_template_desc {
71 char *name;
72 char *fmt;
73 int num_fields;
74 struct ima_template_field **fields;
49}; 75};
50 76
51struct ima_template_entry { 77struct ima_template_entry {
52 u8 digest[IMA_DIGEST_SIZE]; /* sha1 or md5 measurement hash */ 78 u8 digest[TPM_DIGEST_SIZE]; /* sha1 or md5 measurement hash */
53 const char *template_name; 79 struct ima_template_desc *template_desc; /* template descriptor */
54 int template_len; 80 u32 template_data_len;
55 struct ima_template_data template; 81 struct ima_field_data template_data[0]; /* template related data */
56}; 82};
57 83
58struct ima_queue_entry { 84struct ima_queue_entry {
@@ -69,13 +95,22 @@ int ima_fs_init(void);
69void ima_fs_cleanup(void); 95void ima_fs_cleanup(void);
70int ima_inode_alloc(struct inode *inode); 96int ima_inode_alloc(struct inode *inode);
71int ima_add_template_entry(struct ima_template_entry *entry, int violation, 97int ima_add_template_entry(struct ima_template_entry *entry, int violation,
72 const char *op, struct inode *inode); 98 const char *op, struct inode *inode,
73int ima_calc_file_hash(struct file *file, char *digest); 99 const unsigned char *filename);
74int ima_calc_buffer_hash(const void *data, int len, char *digest); 100int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash);
75int ima_calc_boot_aggregate(char *digest); 101int ima_calc_field_array_hash(struct ima_field_data *field_data,
76void ima_add_violation(struct inode *inode, const unsigned char *filename, 102 struct ima_template_desc *desc, int num_fields,
103 struct ima_digest_data *hash);
104int __init ima_calc_boot_aggregate(struct ima_digest_data *hash);
105void ima_add_violation(struct file *file, const unsigned char *filename,
77 const char *op, const char *cause); 106 const char *op, const char *cause);
78int ima_init_crypto(void); 107int ima_init_crypto(void);
108void ima_putc(struct seq_file *m, void *data, int datalen);
109void ima_print_digest(struct seq_file *m, u8 *digest, int size);
110struct ima_template_desc *ima_template_desc_current(void);
111int ima_init_template(void);
112
113int ima_init_template(void);
79 114
80/* 115/*
81 * used to protect h_table and sha_table 116 * used to protect h_table and sha_table
@@ -98,14 +133,22 @@ static inline unsigned long ima_hash_key(u8 *digest)
98int ima_get_action(struct inode *inode, int mask, int function); 133int ima_get_action(struct inode *inode, int mask, int function);
99int ima_must_measure(struct inode *inode, int mask, int function); 134int ima_must_measure(struct inode *inode, int mask, int function);
100int ima_collect_measurement(struct integrity_iint_cache *iint, 135int ima_collect_measurement(struct integrity_iint_cache *iint,
101 struct file *file); 136 struct file *file,
137 struct evm_ima_xattr_data **xattr_value,
138 int *xattr_len);
102void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, 139void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
103 const unsigned char *filename); 140 const unsigned char *filename,
141 struct evm_ima_xattr_data *xattr_value,
142 int xattr_len);
104void ima_audit_measurement(struct integrity_iint_cache *iint, 143void ima_audit_measurement(struct integrity_iint_cache *iint,
105 const unsigned char *filename); 144 const unsigned char *filename);
145int ima_alloc_init_template(struct integrity_iint_cache *iint,
146 struct file *file, const unsigned char *filename,
147 struct evm_ima_xattr_data *xattr_value,
148 int xattr_len, struct ima_template_entry **entry);
106int ima_store_template(struct ima_template_entry *entry, int violation, 149int ima_store_template(struct ima_template_entry *entry, int violation,
107 struct inode *inode); 150 struct inode *inode, const unsigned char *filename);
108void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show); 151void ima_free_template_entry(struct ima_template_entry *entry);
109const char *ima_d_path(struct path *path, char **pathbuf); 152const char *ima_d_path(struct path *path, char **pathbuf);
110 153
111/* rbtree tree calls to lookup, insert, delete 154/* rbtree tree calls to lookup, insert, delete
@@ -131,17 +174,25 @@ void ima_delete_rules(void);
131 174
132#ifdef CONFIG_IMA_APPRAISE 175#ifdef CONFIG_IMA_APPRAISE
133int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, 176int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
134 struct file *file, const unsigned char *filename); 177 struct file *file, const unsigned char *filename,
178 struct evm_ima_xattr_data *xattr_value,
179 int xattr_len);
135int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func); 180int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func);
136void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); 181void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
137enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, 182enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
138 int func); 183 int func);
184void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len,
185 struct ima_digest_data *hash);
186int ima_read_xattr(struct dentry *dentry,
187 struct evm_ima_xattr_data **xattr_value);
139 188
140#else 189#else
141static inline int ima_appraise_measurement(int func, 190static inline int ima_appraise_measurement(int func,
142 struct integrity_iint_cache *iint, 191 struct integrity_iint_cache *iint,
143 struct file *file, 192 struct file *file,
144 const unsigned char *filename) 193 const unsigned char *filename,
194 struct evm_ima_xattr_data *xattr_value,
195 int xattr_len)
145{ 196{
146 return INTEGRITY_UNKNOWN; 197 return INTEGRITY_UNKNOWN;
147} 198}
@@ -162,6 +213,19 @@ static inline enum integrity_status ima_get_cache_status(struct integrity_iint_c
162{ 213{
163 return INTEGRITY_UNKNOWN; 214 return INTEGRITY_UNKNOWN;
164} 215}
216
217static inline void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
218 int xattr_len,
219 struct ima_digest_data *hash)
220{
221}
222
223static inline int ima_read_xattr(struct dentry *dentry,
224 struct evm_ima_xattr_data **xattr_value)
225{
226 return 0;
227}
228
165#endif 229#endif
166 230
167/* LSM based policy rules require audit */ 231/* LSM based policy rules require audit */
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 1c03e8f1e0e1..c38bbce8c6a6 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -18,9 +18,59 @@
18#include <linux/fs.h> 18#include <linux/fs.h>
19#include <linux/xattr.h> 19#include <linux/xattr.h>
20#include <linux/evm.h> 20#include <linux/evm.h>
21#include <crypto/hash_info.h>
21#include "ima.h" 22#include "ima.h"
22 23
23static const char *IMA_TEMPLATE_NAME = "ima"; 24/*
25 * ima_free_template_entry - free an existing template entry
26 */
27void ima_free_template_entry(struct ima_template_entry *entry)
28{
29 int i;
30
31 for (i = 0; i < entry->template_desc->num_fields; i++)
32 kfree(entry->template_data[i].data);
33
34 kfree(entry);
35}
36
37/*
38 * ima_alloc_init_template - create and initialize a new template entry
39 */
40int ima_alloc_init_template(struct integrity_iint_cache *iint,
41 struct file *file, const unsigned char *filename,
42 struct evm_ima_xattr_data *xattr_value,
43 int xattr_len, struct ima_template_entry **entry)
44{
45 struct ima_template_desc *template_desc = ima_template_desc_current();
46 int i, result = 0;
47
48 *entry = kzalloc(sizeof(**entry) + template_desc->num_fields *
49 sizeof(struct ima_field_data), GFP_NOFS);
50 if (!*entry)
51 return -ENOMEM;
52
53 (*entry)->template_desc = template_desc;
54 for (i = 0; i < template_desc->num_fields; i++) {
55 struct ima_template_field *field = template_desc->fields[i];
56 u32 len;
57
58 result = field->field_init(iint, file, filename,
59 xattr_value, xattr_len,
60 &((*entry)->template_data[i]));
61 if (result != 0)
62 goto out;
63
64 len = (*entry)->template_data[i].len;
65 (*entry)->template_data_len += sizeof(len);
66 (*entry)->template_data_len += len;
67 }
68 return 0;
69out:
70 ima_free_template_entry(*entry);
71 *entry = NULL;
72 return result;
73}
24 74
25/* 75/*
26 * ima_store_template - store ima template measurements 76 * ima_store_template - store ima template measurements
@@ -39,28 +89,35 @@ static const char *IMA_TEMPLATE_NAME = "ima";
39 * Returns 0 on success, error code otherwise 89 * Returns 0 on success, error code otherwise
40 */ 90 */
41int ima_store_template(struct ima_template_entry *entry, 91int ima_store_template(struct ima_template_entry *entry,
42 int violation, struct inode *inode) 92 int violation, struct inode *inode,
93 const unsigned char *filename)
43{ 94{
44 const char *op = "add_template_measure"; 95 const char *op = "add_template_measure";
45 const char *audit_cause = "hashing_error"; 96 const char *audit_cause = "hashing_error";
97 char *template_name = entry->template_desc->name;
46 int result; 98 int result;
47 99 struct {
48 memset(entry->digest, 0, sizeof(entry->digest)); 100 struct ima_digest_data hdr;
49 entry->template_name = IMA_TEMPLATE_NAME; 101 char digest[TPM_DIGEST_SIZE];
50 entry->template_len = sizeof(entry->template); 102 } hash;
51 103
52 if (!violation) { 104 if (!violation) {
53 result = ima_calc_buffer_hash(&entry->template, 105 int num_fields = entry->template_desc->num_fields;
54 entry->template_len, 106
55 entry->digest); 107 /* this function uses default algo */
108 hash.hdr.algo = HASH_ALGO_SHA1;
109 result = ima_calc_field_array_hash(&entry->template_data[0],
110 entry->template_desc,
111 num_fields, &hash.hdr);
56 if (result < 0) { 112 if (result < 0) {
57 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, 113 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
58 entry->template_name, op, 114 template_name, op,
59 audit_cause, result, 0); 115 audit_cause, result, 0);
60 return result; 116 return result;
61 } 117 }
118 memcpy(entry->digest, hash.hdr.digest, hash.hdr.length);
62 } 119 }
63 result = ima_add_template_entry(entry, violation, op, inode); 120 result = ima_add_template_entry(entry, violation, op, inode, filename);
64 return result; 121 return result;
65} 122}
66 123
@@ -71,26 +128,26 @@ int ima_store_template(struct ima_template_entry *entry,
71 * By extending the PCR with 0xFF's instead of with zeroes, the PCR 128 * By extending the PCR with 0xFF's instead of with zeroes, the PCR
72 * value is invalidated. 129 * value is invalidated.
73 */ 130 */
74void ima_add_violation(struct inode *inode, const unsigned char *filename, 131void ima_add_violation(struct file *file, const unsigned char *filename,
75 const char *op, const char *cause) 132 const char *op, const char *cause)
76{ 133{
77 struct ima_template_entry *entry; 134 struct ima_template_entry *entry;
135 struct inode *inode = file->f_dentry->d_inode;
78 int violation = 1; 136 int violation = 1;
79 int result; 137 int result;
80 138
81 /* can overflow, only indicator */ 139 /* can overflow, only indicator */
82 atomic_long_inc(&ima_htable.violations); 140 atomic_long_inc(&ima_htable.violations);
83 141
84 entry = kmalloc(sizeof(*entry), GFP_KERNEL); 142 result = ima_alloc_init_template(NULL, file, filename,
85 if (!entry) { 143 NULL, 0, &entry);
144 if (result < 0) {
86 result = -ENOMEM; 145 result = -ENOMEM;
87 goto err_out; 146 goto err_out;
88 } 147 }
89 memset(&entry->template, 0, sizeof(entry->template)); 148 result = ima_store_template(entry, violation, inode, filename);
90 strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX);
91 result = ima_store_template(entry, violation, inode);
92 if (result < 0) 149 if (result < 0)
93 kfree(entry); 150 ima_free_template_entry(entry);
94err_out: 151err_out:
95 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, 152 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
96 op, cause, result, 0); 153 op, cause, result, 0);
@@ -138,20 +195,42 @@ int ima_must_measure(struct inode *inode, int mask, int function)
138 * Return 0 on success, error code otherwise 195 * Return 0 on success, error code otherwise
139 */ 196 */
140int ima_collect_measurement(struct integrity_iint_cache *iint, 197int ima_collect_measurement(struct integrity_iint_cache *iint,
141 struct file *file) 198 struct file *file,
199 struct evm_ima_xattr_data **xattr_value,
200 int *xattr_len)
142{ 201{
143 struct inode *inode = file_inode(file); 202 struct inode *inode = file_inode(file);
144 const char *filename = file->f_dentry->d_name.name; 203 const char *filename = file->f_dentry->d_name.name;
145 int result = 0; 204 int result = 0;
205 struct {
206 struct ima_digest_data hdr;
207 char digest[IMA_MAX_DIGEST_SIZE];
208 } hash;
209
210 if (xattr_value)
211 *xattr_len = ima_read_xattr(file->f_dentry, xattr_value);
146 212
147 if (!(iint->flags & IMA_COLLECTED)) { 213 if (!(iint->flags & IMA_COLLECTED)) {
148 u64 i_version = file_inode(file)->i_version; 214 u64 i_version = file_inode(file)->i_version;
149 215
150 iint->ima_xattr.type = IMA_XATTR_DIGEST; 216 /* use default hash algorithm */
151 result = ima_calc_file_hash(file, iint->ima_xattr.digest); 217 hash.hdr.algo = ima_hash_algo;
218
219 if (xattr_value)
220 ima_get_hash_algo(*xattr_value, *xattr_len, &hash.hdr);
221
222 result = ima_calc_file_hash(file, &hash.hdr);
152 if (!result) { 223 if (!result) {
153 iint->version = i_version; 224 int length = sizeof(hash.hdr) + hash.hdr.length;
154 iint->flags |= IMA_COLLECTED; 225 void *tmpbuf = krealloc(iint->ima_hash, length,
226 GFP_NOFS);
227 if (tmpbuf) {
228 iint->ima_hash = tmpbuf;
229 memcpy(iint->ima_hash, &hash, length);
230 iint->version = i_version;
231 iint->flags |= IMA_COLLECTED;
232 } else
233 result = -ENOMEM;
155 } 234 }
156 } 235 }
157 if (result) 236 if (result)
@@ -177,7 +256,9 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
177 * Must be called with iint->mutex held. 256 * Must be called with iint->mutex held.
178 */ 257 */
179void ima_store_measurement(struct integrity_iint_cache *iint, 258void ima_store_measurement(struct integrity_iint_cache *iint,
180 struct file *file, const unsigned char *filename) 259 struct file *file, const unsigned char *filename,
260 struct evm_ima_xattr_data *xattr_value,
261 int xattr_len)
181{ 262{
182 const char *op = "add_template_measure"; 263 const char *op = "add_template_measure";
183 const char *audit_cause = "ENOMEM"; 264 const char *audit_cause = "ENOMEM";
@@ -189,37 +270,35 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
189 if (iint->flags & IMA_MEASURED) 270 if (iint->flags & IMA_MEASURED)
190 return; 271 return;
191 272
192 entry = kmalloc(sizeof(*entry), GFP_KERNEL); 273 result = ima_alloc_init_template(iint, file, filename,
193 if (!entry) { 274 xattr_value, xattr_len, &entry);
275 if (result < 0) {
194 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, 276 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
195 op, audit_cause, result, 0); 277 op, audit_cause, result, 0);
196 return; 278 return;
197 } 279 }
198 memset(&entry->template, 0, sizeof(entry->template));
199 memcpy(entry->template.digest, iint->ima_xattr.digest, IMA_DIGEST_SIZE);
200 strcpy(entry->template.file_name,
201 (strlen(filename) > IMA_EVENT_NAME_LEN_MAX) ?
202 file->f_dentry->d_name.name : filename);
203 280
204 result = ima_store_template(entry, violation, inode); 281 result = ima_store_template(entry, violation, inode, filename);
205 if (!result || result == -EEXIST) 282 if (!result || result == -EEXIST)
206 iint->flags |= IMA_MEASURED; 283 iint->flags |= IMA_MEASURED;
207 if (result < 0) 284 if (result < 0)
208 kfree(entry); 285 ima_free_template_entry(entry);
209} 286}
210 287
211void ima_audit_measurement(struct integrity_iint_cache *iint, 288void ima_audit_measurement(struct integrity_iint_cache *iint,
212 const unsigned char *filename) 289 const unsigned char *filename)
213{ 290{
214 struct audit_buffer *ab; 291 struct audit_buffer *ab;
215 char hash[(IMA_DIGEST_SIZE * 2) + 1]; 292 char hash[(iint->ima_hash->length * 2) + 1];
293 const char *algo_name = hash_algo_name[iint->ima_hash->algo];
294 char algo_hash[sizeof(hash) + strlen(algo_name) + 2];
216 int i; 295 int i;
217 296
218 if (iint->flags & IMA_AUDITED) 297 if (iint->flags & IMA_AUDITED)
219 return; 298 return;
220 299
221 for (i = 0; i < IMA_DIGEST_SIZE; i++) 300 for (i = 0; i < iint->ima_hash->length; i++)
222 hex_byte_pack(hash + (i * 2), iint->ima_xattr.digest[i]); 301 hex_byte_pack(hash + (i * 2), iint->ima_hash->digest[i]);
223 hash[i * 2] = '\0'; 302 hash[i * 2] = '\0';
224 303
225 ab = audit_log_start(current->audit_context, GFP_KERNEL, 304 ab = audit_log_start(current->audit_context, GFP_KERNEL,
@@ -230,7 +309,8 @@ void ima_audit_measurement(struct integrity_iint_cache *iint,
230 audit_log_format(ab, "file="); 309 audit_log_format(ab, "file=");
231 audit_log_untrustedstring(ab, filename); 310 audit_log_untrustedstring(ab, filename);
232 audit_log_format(ab, " hash="); 311 audit_log_format(ab, " hash=");
233 audit_log_untrustedstring(ab, hash); 312 snprintf(algo_hash, sizeof(algo_hash), "%s:%s", algo_name, hash);
313 audit_log_untrustedstring(ab, algo_hash);
234 314
235 audit_log_task_info(ab, current); 315 audit_log_task_info(ab, current);
236 audit_log_end(ab); 316 audit_log_end(ab);
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 2d4becab8918..734e9468aca0 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -15,6 +15,7 @@
15#include <linux/magic.h> 15#include <linux/magic.h>
16#include <linux/ima.h> 16#include <linux/ima.h>
17#include <linux/evm.h> 17#include <linux/evm.h>
18#include <crypto/hash_info.h>
18 19
19#include "ima.h" 20#include "ima.h"
20 21
@@ -43,19 +44,31 @@ int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func)
43} 44}
44 45
45static int ima_fix_xattr(struct dentry *dentry, 46static int ima_fix_xattr(struct dentry *dentry,
46 struct integrity_iint_cache *iint) 47 struct integrity_iint_cache *iint)
47{ 48{
48 iint->ima_xattr.type = IMA_XATTR_DIGEST; 49 int rc, offset;
49 return __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA, 50 u8 algo = iint->ima_hash->algo;
50 (u8 *)&iint->ima_xattr, 51
51 sizeof(iint->ima_xattr), 0); 52 if (algo <= HASH_ALGO_SHA1) {
53 offset = 1;
54 iint->ima_hash->xattr.sha1.type = IMA_XATTR_DIGEST;
55 } else {
56 offset = 0;
57 iint->ima_hash->xattr.ng.type = IMA_XATTR_DIGEST_NG;
58 iint->ima_hash->xattr.ng.algo = algo;
59 }
60 rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA,
61 &iint->ima_hash->xattr.data[offset],
62 (sizeof(iint->ima_hash->xattr) - offset) +
63 iint->ima_hash->length, 0);
64 return rc;
52} 65}
53 66
54/* Return specific func appraised cached result */ 67/* Return specific func appraised cached result */
55enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, 68enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
56 int func) 69 int func)
57{ 70{
58 switch(func) { 71 switch (func) {
59 case MMAP_CHECK: 72 case MMAP_CHECK:
60 return iint->ima_mmap_status; 73 return iint->ima_mmap_status;
61 case BPRM_CHECK: 74 case BPRM_CHECK:
@@ -71,7 +84,7 @@ enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
71static void ima_set_cache_status(struct integrity_iint_cache *iint, 84static void ima_set_cache_status(struct integrity_iint_cache *iint,
72 int func, enum integrity_status status) 85 int func, enum integrity_status status)
73{ 86{
74 switch(func) { 87 switch (func) {
75 case MMAP_CHECK: 88 case MMAP_CHECK:
76 iint->ima_mmap_status = status; 89 iint->ima_mmap_status = status;
77 break; 90 break;
@@ -90,7 +103,7 @@ static void ima_set_cache_status(struct integrity_iint_cache *iint,
90 103
91static void ima_cache_flags(struct integrity_iint_cache *iint, int func) 104static void ima_cache_flags(struct integrity_iint_cache *iint, int func)
92{ 105{
93 switch(func) { 106 switch (func) {
94 case MMAP_CHECK: 107 case MMAP_CHECK:
95 iint->flags |= (IMA_MMAP_APPRAISED | IMA_APPRAISED); 108 iint->flags |= (IMA_MMAP_APPRAISED | IMA_APPRAISED);
96 break; 109 break;
@@ -107,6 +120,50 @@ static void ima_cache_flags(struct integrity_iint_cache *iint, int func)
107 } 120 }
108} 121}
109 122
123void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len,
124 struct ima_digest_data *hash)
125{
126 struct signature_v2_hdr *sig;
127
128 if (!xattr_value || xattr_len < 2)
129 return;
130
131 switch (xattr_value->type) {
132 case EVM_IMA_XATTR_DIGSIG:
133 sig = (typeof(sig))xattr_value;
134 if (sig->version != 2 || xattr_len <= sizeof(*sig))
135 return;
136 hash->algo = sig->hash_algo;
137 break;
138 case IMA_XATTR_DIGEST_NG:
139 hash->algo = xattr_value->digest[0];
140 break;
141 case IMA_XATTR_DIGEST:
142 /* this is for backward compatibility */
143 if (xattr_len == 21) {
144 unsigned int zero = 0;
145 if (!memcmp(&xattr_value->digest[16], &zero, 4))
146 hash->algo = HASH_ALGO_MD5;
147 else
148 hash->algo = HASH_ALGO_SHA1;
149 } else if (xattr_len == 17)
150 hash->algo = HASH_ALGO_MD5;
151 break;
152 }
153}
154
155int ima_read_xattr(struct dentry *dentry,
156 struct evm_ima_xattr_data **xattr_value)
157{
158 struct inode *inode = dentry->d_inode;
159
160 if (!inode->i_op->getxattr)
161 return 0;
162
163 return vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)xattr_value,
164 0, GFP_NOFS);
165}
166
110/* 167/*
111 * ima_appraise_measurement - appraise file measurement 168 * ima_appraise_measurement - appraise file measurement
112 * 169 *
@@ -116,23 +173,22 @@ static void ima_cache_flags(struct integrity_iint_cache *iint, int func)
116 * Return 0 on success, error code otherwise 173 * Return 0 on success, error code otherwise
117 */ 174 */
118int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, 175int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
119 struct file *file, const unsigned char *filename) 176 struct file *file, const unsigned char *filename,
177 struct evm_ima_xattr_data *xattr_value,
178 int xattr_len)
120{ 179{
121 struct dentry *dentry = file->f_dentry; 180 struct dentry *dentry = file->f_dentry;
122 struct inode *inode = dentry->d_inode; 181 struct inode *inode = dentry->d_inode;
123 struct evm_ima_xattr_data *xattr_value = NULL;
124 enum integrity_status status = INTEGRITY_UNKNOWN; 182 enum integrity_status status = INTEGRITY_UNKNOWN;
125 const char *op = "appraise_data"; 183 const char *op = "appraise_data";
126 char *cause = "unknown"; 184 char *cause = "unknown";
127 int rc; 185 int rc = xattr_len, hash_start = 0;
128 186
129 if (!ima_appraise) 187 if (!ima_appraise)
130 return 0; 188 return 0;
131 if (!inode->i_op->getxattr) 189 if (!inode->i_op->getxattr)
132 return INTEGRITY_UNKNOWN; 190 return INTEGRITY_UNKNOWN;
133 191
134 rc = vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)&xattr_value,
135 0, GFP_NOFS);
136 if (rc <= 0) { 192 if (rc <= 0) {
137 if (rc && rc != -ENODATA) 193 if (rc && rc != -ENODATA)
138 goto out; 194 goto out;
@@ -153,14 +209,25 @@ int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
153 goto out; 209 goto out;
154 } 210 }
155 switch (xattr_value->type) { 211 switch (xattr_value->type) {
212 case IMA_XATTR_DIGEST_NG:
213 /* first byte contains algorithm id */
214 hash_start = 1;
156 case IMA_XATTR_DIGEST: 215 case IMA_XATTR_DIGEST:
157 if (iint->flags & IMA_DIGSIG_REQUIRED) { 216 if (iint->flags & IMA_DIGSIG_REQUIRED) {
158 cause = "IMA signature required"; 217 cause = "IMA signature required";
159 status = INTEGRITY_FAIL; 218 status = INTEGRITY_FAIL;
160 break; 219 break;
161 } 220 }
162 rc = memcmp(xattr_value->digest, iint->ima_xattr.digest, 221 if (xattr_len - sizeof(xattr_value->type) - hash_start >=
163 IMA_DIGEST_SIZE); 222 iint->ima_hash->length)
223 /* xattr length may be longer. md5 hash in previous
224 version occupied 20 bytes in xattr, instead of 16
225 */
226 rc = memcmp(&xattr_value->digest[hash_start],
227 iint->ima_hash->digest,
228 iint->ima_hash->length);
229 else
230 rc = -EINVAL;
164 if (rc) { 231 if (rc) {
165 cause = "invalid-hash"; 232 cause = "invalid-hash";
166 status = INTEGRITY_FAIL; 233 status = INTEGRITY_FAIL;
@@ -171,9 +238,9 @@ int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
171 case EVM_IMA_XATTR_DIGSIG: 238 case EVM_IMA_XATTR_DIGSIG:
172 iint->flags |= IMA_DIGSIG; 239 iint->flags |= IMA_DIGSIG;
173 rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA, 240 rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA,
174 xattr_value->digest, rc - 1, 241 (const char *)xattr_value, rc,
175 iint->ima_xattr.digest, 242 iint->ima_hash->digest,
176 IMA_DIGEST_SIZE); 243 iint->ima_hash->length);
177 if (rc == -EOPNOTSUPP) { 244 if (rc == -EOPNOTSUPP) {
178 status = INTEGRITY_UNKNOWN; 245 status = INTEGRITY_UNKNOWN;
179 } else if (rc) { 246 } else if (rc) {
@@ -203,7 +270,6 @@ out:
203 ima_cache_flags(iint, func); 270 ima_cache_flags(iint, func);
204 } 271 }
205 ima_set_cache_status(iint, func, status); 272 ima_set_cache_status(iint, func, status);
206 kfree(xattr_value);
207 return status; 273 return status;
208} 274}
209 275
@@ -219,7 +285,7 @@ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
219 if (iint->flags & IMA_DIGSIG) 285 if (iint->flags & IMA_DIGSIG)
220 return; 286 return;
221 287
222 rc = ima_collect_measurement(iint, file); 288 rc = ima_collect_measurement(iint, file, NULL, NULL);
223 if (rc < 0) 289 if (rc < 0)
224 return; 290 return;
225 291
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index a02e0791cf15..fdf60def52e9 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -20,6 +20,7 @@
20#include <linux/err.h> 20#include <linux/err.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <crypto/hash.h> 22#include <crypto/hash.h>
23#include <crypto/hash_info.h>
23#include "ima.h" 24#include "ima.h"
24 25
25static struct crypto_shash *ima_shash_tfm; 26static struct crypto_shash *ima_shash_tfm;
@@ -28,31 +29,58 @@ int ima_init_crypto(void)
28{ 29{
29 long rc; 30 long rc;
30 31
31 ima_shash_tfm = crypto_alloc_shash(ima_hash, 0, 0); 32 ima_shash_tfm = crypto_alloc_shash(hash_algo_name[ima_hash_algo], 0, 0);
32 if (IS_ERR(ima_shash_tfm)) { 33 if (IS_ERR(ima_shash_tfm)) {
33 rc = PTR_ERR(ima_shash_tfm); 34 rc = PTR_ERR(ima_shash_tfm);
34 pr_err("Can not allocate %s (reason: %ld)\n", ima_hash, rc); 35 pr_err("Can not allocate %s (reason: %ld)\n",
36 hash_algo_name[ima_hash_algo], rc);
35 return rc; 37 return rc;
36 } 38 }
37 return 0; 39 return 0;
38} 40}
39 41
42static struct crypto_shash *ima_alloc_tfm(enum hash_algo algo)
43{
44 struct crypto_shash *tfm = ima_shash_tfm;
45 int rc;
46
47 if (algo != ima_hash_algo && algo < HASH_ALGO__LAST) {
48 tfm = crypto_alloc_shash(hash_algo_name[algo], 0, 0);
49 if (IS_ERR(tfm)) {
50 rc = PTR_ERR(tfm);
51 pr_err("Can not allocate %s (reason: %d)\n",
52 hash_algo_name[algo], rc);
53 }
54 }
55 return tfm;
56}
57
58static void ima_free_tfm(struct crypto_shash *tfm)
59{
60 if (tfm != ima_shash_tfm)
61 crypto_free_shash(tfm);
62}
63
40/* 64/*
41 * Calculate the MD5/SHA1 file digest 65 * Calculate the MD5/SHA1 file digest
42 */ 66 */
43int ima_calc_file_hash(struct file *file, char *digest) 67static int ima_calc_file_hash_tfm(struct file *file,
68 struct ima_digest_data *hash,
69 struct crypto_shash *tfm)
44{ 70{
45 loff_t i_size, offset = 0; 71 loff_t i_size, offset = 0;
46 char *rbuf; 72 char *rbuf;
47 int rc, read = 0; 73 int rc, read = 0;
48 struct { 74 struct {
49 struct shash_desc shash; 75 struct shash_desc shash;
50 char ctx[crypto_shash_descsize(ima_shash_tfm)]; 76 char ctx[crypto_shash_descsize(tfm)];
51 } desc; 77 } desc;
52 78
53 desc.shash.tfm = ima_shash_tfm; 79 desc.shash.tfm = tfm;
54 desc.shash.flags = 0; 80 desc.shash.flags = 0;
55 81
82 hash->length = crypto_shash_digestsize(tfm);
83
56 rc = crypto_shash_init(&desc.shash); 84 rc = crypto_shash_init(&desc.shash);
57 if (rc != 0) 85 if (rc != 0)
58 return rc; 86 return rc;
@@ -85,27 +113,90 @@ int ima_calc_file_hash(struct file *file, char *digest)
85 } 113 }
86 kfree(rbuf); 114 kfree(rbuf);
87 if (!rc) 115 if (!rc)
88 rc = crypto_shash_final(&desc.shash, digest); 116 rc = crypto_shash_final(&desc.shash, hash->digest);
89 if (read) 117 if (read)
90 file->f_mode &= ~FMODE_READ; 118 file->f_mode &= ~FMODE_READ;
91out: 119out:
92 return rc; 120 return rc;
93} 121}
94 122
123int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
124{
125 struct crypto_shash *tfm;
126 int rc;
127
128 tfm = ima_alloc_tfm(hash->algo);
129 if (IS_ERR(tfm))
130 return PTR_ERR(tfm);
131
132 rc = ima_calc_file_hash_tfm(file, hash, tfm);
133
134 ima_free_tfm(tfm);
135
136 return rc;
137}
138
95/* 139/*
96 * Calculate the hash of a given buffer 140 * Calculate the hash of template data
97 */ 141 */
98int ima_calc_buffer_hash(const void *data, int len, char *digest) 142static int ima_calc_field_array_hash_tfm(struct ima_field_data *field_data,
143 struct ima_template_desc *td,
144 int num_fields,
145 struct ima_digest_data *hash,
146 struct crypto_shash *tfm)
99{ 147{
100 struct { 148 struct {
101 struct shash_desc shash; 149 struct shash_desc shash;
102 char ctx[crypto_shash_descsize(ima_shash_tfm)]; 150 char ctx[crypto_shash_descsize(tfm)];
103 } desc; 151 } desc;
152 int rc, i;
104 153
105 desc.shash.tfm = ima_shash_tfm; 154 desc.shash.tfm = tfm;
106 desc.shash.flags = 0; 155 desc.shash.flags = 0;
107 156
108 return crypto_shash_digest(&desc.shash, data, len, digest); 157 hash->length = crypto_shash_digestsize(tfm);
158
159 rc = crypto_shash_init(&desc.shash);
160 if (rc != 0)
161 return rc;
162
163 for (i = 0; i < num_fields; i++) {
164 if (strcmp(td->name, IMA_TEMPLATE_IMA_NAME) != 0) {
165 rc = crypto_shash_update(&desc.shash,
166 (const u8 *) &field_data[i].len,
167 sizeof(field_data[i].len));
168 if (rc)
169 break;
170 }
171 rc = crypto_shash_update(&desc.shash, field_data[i].data,
172 field_data[i].len);
173 if (rc)
174 break;
175 }
176
177 if (!rc)
178 rc = crypto_shash_final(&desc.shash, hash->digest);
179
180 return rc;
181}
182
183int ima_calc_field_array_hash(struct ima_field_data *field_data,
184 struct ima_template_desc *desc, int num_fields,
185 struct ima_digest_data *hash)
186{
187 struct crypto_shash *tfm;
188 int rc;
189
190 tfm = ima_alloc_tfm(hash->algo);
191 if (IS_ERR(tfm))
192 return PTR_ERR(tfm);
193
194 rc = ima_calc_field_array_hash_tfm(field_data, desc, num_fields,
195 hash, tfm);
196
197 ima_free_tfm(tfm);
198
199 return rc;
109} 200}
110 201
111static void __init ima_pcrread(int idx, u8 *pcr) 202static void __init ima_pcrread(int idx, u8 *pcr)
@@ -120,16 +211,17 @@ static void __init ima_pcrread(int idx, u8 *pcr)
120/* 211/*
121 * Calculate the boot aggregate hash 212 * Calculate the boot aggregate hash
122 */ 213 */
123int __init ima_calc_boot_aggregate(char *digest) 214static int __init ima_calc_boot_aggregate_tfm(char *digest,
215 struct crypto_shash *tfm)
124{ 216{
125 u8 pcr_i[IMA_DIGEST_SIZE]; 217 u8 pcr_i[TPM_DIGEST_SIZE];
126 int rc, i; 218 int rc, i;
127 struct { 219 struct {
128 struct shash_desc shash; 220 struct shash_desc shash;
129 char ctx[crypto_shash_descsize(ima_shash_tfm)]; 221 char ctx[crypto_shash_descsize(tfm)];
130 } desc; 222 } desc;
131 223
132 desc.shash.tfm = ima_shash_tfm; 224 desc.shash.tfm = tfm;
133 desc.shash.flags = 0; 225 desc.shash.flags = 0;
134 226
135 rc = crypto_shash_init(&desc.shash); 227 rc = crypto_shash_init(&desc.shash);
@@ -140,9 +232,26 @@ int __init ima_calc_boot_aggregate(char *digest)
140 for (i = TPM_PCR0; i < TPM_PCR8; i++) { 232 for (i = TPM_PCR0; i < TPM_PCR8; i++) {
141 ima_pcrread(i, pcr_i); 233 ima_pcrread(i, pcr_i);
142 /* now accumulate with current aggregate */ 234 /* now accumulate with current aggregate */
143 rc = crypto_shash_update(&desc.shash, pcr_i, IMA_DIGEST_SIZE); 235 rc = crypto_shash_update(&desc.shash, pcr_i, TPM_DIGEST_SIZE);
144 } 236 }
145 if (!rc) 237 if (!rc)
146 crypto_shash_final(&desc.shash, digest); 238 crypto_shash_final(&desc.shash, digest);
147 return rc; 239 return rc;
148} 240}
241
242int __init ima_calc_boot_aggregate(struct ima_digest_data *hash)
243{
244 struct crypto_shash *tfm;
245 int rc;
246
247 tfm = ima_alloc_tfm(hash->algo);
248 if (IS_ERR(tfm))
249 return PTR_ERR(tfm);
250
251 hash->length = crypto_shash_digestsize(tfm);
252 rc = ima_calc_boot_aggregate_tfm(hash->digest, tfm);
253
254 ima_free_tfm(tfm);
255
256 return rc;
257}
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 38477c9c3415..db01125926bd 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -88,8 +88,7 @@ static void *ima_measurements_next(struct seq_file *m, void *v, loff_t *pos)
88 * against concurrent list-extension 88 * against concurrent list-extension
89 */ 89 */
90 rcu_read_lock(); 90 rcu_read_lock();
91 qe = list_entry_rcu(qe->later.next, 91 qe = list_entry_rcu(qe->later.next, struct ima_queue_entry, later);
92 struct ima_queue_entry, later);
93 rcu_read_unlock(); 92 rcu_read_unlock();
94 (*pos)++; 93 (*pos)++;
95 94
@@ -100,7 +99,7 @@ static void ima_measurements_stop(struct seq_file *m, void *v)
100{ 99{
101} 100}
102 101
103static void ima_putc(struct seq_file *m, void *data, int datalen) 102void ima_putc(struct seq_file *m, void *data, int datalen)
104{ 103{
105 while (datalen--) 104 while (datalen--)
106 seq_putc(m, *(char *)data++); 105 seq_putc(m, *(char *)data++);
@@ -111,6 +110,7 @@ static void ima_putc(struct seq_file *m, void *data, int datalen)
111 * char[20]=template digest 110 * char[20]=template digest
112 * 32bit-le=template name size 111 * 32bit-le=template name size
113 * char[n]=template name 112 * char[n]=template name
113 * [eventdata length]
114 * eventdata[n]=template specific data 114 * eventdata[n]=template specific data
115 */ 115 */
116static int ima_measurements_show(struct seq_file *m, void *v) 116static int ima_measurements_show(struct seq_file *m, void *v)
@@ -120,6 +120,8 @@ static int ima_measurements_show(struct seq_file *m, void *v)
120 struct ima_template_entry *e; 120 struct ima_template_entry *e;
121 int namelen; 121 int namelen;
122 u32 pcr = CONFIG_IMA_MEASURE_PCR_IDX; 122 u32 pcr = CONFIG_IMA_MEASURE_PCR_IDX;
123 bool is_ima_template = false;
124 int i;
123 125
124 /* get entry */ 126 /* get entry */
125 e = qe->entry; 127 e = qe->entry;
@@ -134,18 +136,32 @@ static int ima_measurements_show(struct seq_file *m, void *v)
134 ima_putc(m, &pcr, sizeof pcr); 136 ima_putc(m, &pcr, sizeof pcr);
135 137
136 /* 2nd: template digest */ 138 /* 2nd: template digest */
137 ima_putc(m, e->digest, IMA_DIGEST_SIZE); 139 ima_putc(m, e->digest, TPM_DIGEST_SIZE);
138 140
139 /* 3rd: template name size */ 141 /* 3rd: template name size */
140 namelen = strlen(e->template_name); 142 namelen = strlen(e->template_desc->name);
141 ima_putc(m, &namelen, sizeof namelen); 143 ima_putc(m, &namelen, sizeof namelen);
142 144
143 /* 4th: template name */ 145 /* 4th: template name */
144 ima_putc(m, (void *)e->template_name, namelen); 146 ima_putc(m, e->template_desc->name, namelen);
147
148 /* 5th: template length (except for 'ima' template) */
149 if (strcmp(e->template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0)
150 is_ima_template = true;
151
152 if (!is_ima_template)
153 ima_putc(m, &e->template_data_len,
154 sizeof(e->template_data_len));
155
156 /* 6th: template specific data */
157 for (i = 0; i < e->template_desc->num_fields; i++) {
158 enum ima_show_type show = IMA_SHOW_BINARY;
159 struct ima_template_field *field = e->template_desc->fields[i];
145 160
146 /* 5th: template specific data */ 161 if (is_ima_template && strcmp(field->field_id, "d") == 0)
147 ima_template_show(m, (struct ima_template_data *)&e->template, 162 show = IMA_SHOW_BINARY_NO_FIELD_LEN;
148 IMA_SHOW_BINARY); 163 field->field_show(m, show, &e->template_data[i]);
164 }
149 return 0; 165 return 0;
150} 166}
151 167
@@ -168,41 +184,21 @@ static const struct file_operations ima_measurements_ops = {
168 .release = seq_release, 184 .release = seq_release,
169}; 185};
170 186
171static void ima_print_digest(struct seq_file *m, u8 *digest) 187void ima_print_digest(struct seq_file *m, u8 *digest, int size)
172{ 188{
173 int i; 189 int i;
174 190
175 for (i = 0; i < IMA_DIGEST_SIZE; i++) 191 for (i = 0; i < size; i++)
176 seq_printf(m, "%02x", *(digest + i)); 192 seq_printf(m, "%02x", *(digest + i));
177} 193}
178 194
179void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show)
180{
181 struct ima_template_data *entry = e;
182 int namelen;
183
184 switch (show) {
185 case IMA_SHOW_ASCII:
186 ima_print_digest(m, entry->digest);
187 seq_printf(m, " %s\n", entry->file_name);
188 break;
189 case IMA_SHOW_BINARY:
190 ima_putc(m, entry->digest, IMA_DIGEST_SIZE);
191
192 namelen = strlen(entry->file_name);
193 ima_putc(m, &namelen, sizeof namelen);
194 ima_putc(m, entry->file_name, namelen);
195 default:
196 break;
197 }
198}
199
200/* print in ascii */ 195/* print in ascii */
201static int ima_ascii_measurements_show(struct seq_file *m, void *v) 196static int ima_ascii_measurements_show(struct seq_file *m, void *v)
202{ 197{
203 /* the list never shrinks, so we don't need a lock here */ 198 /* the list never shrinks, so we don't need a lock here */
204 struct ima_queue_entry *qe = v; 199 struct ima_queue_entry *qe = v;
205 struct ima_template_entry *e; 200 struct ima_template_entry *e;
201 int i;
206 202
207 /* get entry */ 203 /* get entry */
208 e = qe->entry; 204 e = qe->entry;
@@ -213,14 +209,21 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v)
213 seq_printf(m, "%2d ", CONFIG_IMA_MEASURE_PCR_IDX); 209 seq_printf(m, "%2d ", CONFIG_IMA_MEASURE_PCR_IDX);
214 210
215 /* 2nd: SHA1 template hash */ 211 /* 2nd: SHA1 template hash */
216 ima_print_digest(m, e->digest); 212 ima_print_digest(m, e->digest, TPM_DIGEST_SIZE);
217 213
218 /* 3th: template name */ 214 /* 3th: template name */
219 seq_printf(m, " %s ", e->template_name); 215 seq_printf(m, " %s", e->template_desc->name);
220 216
221 /* 4th: template specific data */ 217 /* 4th: template specific data */
222 ima_template_show(m, (struct ima_template_data *)&e->template, 218 for (i = 0; i < e->template_desc->num_fields; i++) {
223 IMA_SHOW_ASCII); 219 seq_puts(m, " ");
220 if (e->template_data[i].len == 0)
221 continue;
222
223 e->template_desc->fields[i]->field_show(m, IMA_SHOW_ASCII,
224 &e->template_data[i]);
225 }
226 seq_puts(m, "\n");
224 return 0; 227 return 0;
225} 228}
226 229
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index 162ea723db3d..37122768554a 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -18,6 +18,7 @@
18#include <linux/scatterlist.h> 18#include <linux/scatterlist.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/err.h> 20#include <linux/err.h>
21#include <crypto/hash_info.h>
21#include "ima.h" 22#include "ima.h"
22 23
23/* name for boot aggregate entry */ 24/* name for boot aggregate entry */
@@ -42,30 +43,39 @@ int ima_used_chip;
42static void __init ima_add_boot_aggregate(void) 43static void __init ima_add_boot_aggregate(void)
43{ 44{
44 struct ima_template_entry *entry; 45 struct ima_template_entry *entry;
46 struct integrity_iint_cache tmp_iint, *iint = &tmp_iint;
45 const char *op = "add_boot_aggregate"; 47 const char *op = "add_boot_aggregate";
46 const char *audit_cause = "ENOMEM"; 48 const char *audit_cause = "ENOMEM";
47 int result = -ENOMEM; 49 int result = -ENOMEM;
48 int violation = 1; 50 int violation = 0;
51 struct {
52 struct ima_digest_data hdr;
53 char digest[TPM_DIGEST_SIZE];
54 } hash;
49 55
50 entry = kmalloc(sizeof(*entry), GFP_KERNEL); 56 memset(iint, 0, sizeof(*iint));
51 if (!entry) 57 memset(&hash, 0, sizeof(hash));
52 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;
53 61
54 memset(&entry->template, 0, sizeof(entry->template));
55 strncpy(entry->template.file_name, boot_aggregate_name,
56 IMA_EVENT_NAME_LEN_MAX);
57 if (ima_used_chip) { 62 if (ima_used_chip) {
58 violation = 0; 63 result = ima_calc_boot_aggregate(&hash.hdr);
59 result = ima_calc_boot_aggregate(entry->template.digest);
60 if (result < 0) { 64 if (result < 0) {
61 audit_cause = "hashing_error"; 65 audit_cause = "hashing_error";
62 kfree(entry);
63 goto err_out; 66 goto err_out;
64 } 67 }
65 } 68 }
66 result = ima_store_template(entry, violation, NULL); 69
70 result = ima_alloc_init_template(iint, NULL, boot_aggregate_name,
71 NULL, 0, &entry);
72 if (result < 0)
73 return;
74
75 result = ima_store_template(entry, violation, NULL,
76 boot_aggregate_name);
67 if (result < 0) 77 if (result < 0)
68 kfree(entry); 78 ima_free_template_entry(entry);
69 return; 79 return;
70err_out: 80err_out:
71 integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, boot_aggregate_name, op, 81 integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, boot_aggregate_name, op,
@@ -74,7 +84,7 @@ err_out:
74 84
75int __init ima_init(void) 85int __init ima_init(void)
76{ 86{
77 u8 pcr_i[IMA_DIGEST_SIZE]; 87 u8 pcr_i[TPM_DIGEST_SIZE];
78 int rc; 88 int rc;
79 89
80 ima_used_chip = 0; 90 ima_used_chip = 0;
@@ -88,6 +98,10 @@ int __init ima_init(void)
88 rc = ima_init_crypto(); 98 rc = ima_init_crypto();
89 if (rc) 99 if (rc)
90 return rc; 100 return rc;
101 rc = ima_init_template();
102 if (rc != 0)
103 return rc;
104
91 ima_add_boot_aggregate(); /* boot aggregate must be first entry */ 105 ima_add_boot_aggregate(); /* boot aggregate must be first entry */
92 ima_init_policy(); 106 ima_init_policy();
93 107
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index e9508d5bbfcf..149ee1119f87 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -24,6 +24,7 @@
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/xattr.h> 25#include <linux/xattr.h>
26#include <linux/ima.h> 26#include <linux/ima.h>
27#include <crypto/hash_info.h>
27 28
28#include "ima.h" 29#include "ima.h"
29 30
@@ -35,11 +36,33 @@ int ima_appraise = IMA_APPRAISE_ENFORCE;
35int ima_appraise; 36int ima_appraise;
36#endif 37#endif
37 38
38char *ima_hash = "sha1"; 39int ima_hash_algo = HASH_ALGO_SHA1;
40static int hash_setup_done;
41
39static int __init hash_setup(char *str) 42static int __init hash_setup(char *str)
40{ 43{
41 if (strncmp(str, "md5", 3) == 0) 44 struct ima_template_desc *template_desc = ima_template_desc_current();
42 ima_hash = "md5"; 45 int i;
46
47 if (hash_setup_done)
48 return 1;
49
50 if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) {
51 if (strncmp(str, "sha1", 4) == 0)
52 ima_hash_algo = HASH_ALGO_SHA1;
53 else if (strncmp(str, "md5", 3) == 0)
54 ima_hash_algo = HASH_ALGO_MD5;
55 goto out;
56 }
57
58 for (i = 0; i < HASH_ALGO__LAST; i++) {
59 if (strcmp(str, hash_algo_name[i]) == 0) {
60 ima_hash_algo = i;
61 break;
62 }
63 }
64out:
65 hash_setup_done = 1;
43 return 1; 66 return 1;
44} 67}
45__setup("ima_hash=", hash_setup); 68__setup("ima_hash=", hash_setup);
@@ -92,10 +115,9 @@ out:
92 pathname = dentry->d_name.name; 115 pathname = dentry->d_name.name;
93 116
94 if (send_tomtou) 117 if (send_tomtou)
95 ima_add_violation(inode, pathname, 118 ima_add_violation(file, pathname, "invalid_pcr", "ToMToU");
96 "invalid_pcr", "ToMToU");
97 if (send_writers) 119 if (send_writers)
98 ima_add_violation(inode, pathname, 120 ima_add_violation(file, pathname,
99 "invalid_pcr", "open_writers"); 121 "invalid_pcr", "open_writers");
100 kfree(pathbuf); 122 kfree(pathbuf);
101} 123}
@@ -144,9 +166,12 @@ static int process_measurement(struct file *file, const char *filename,
144{ 166{
145 struct inode *inode = file_inode(file); 167 struct inode *inode = file_inode(file);
146 struct integrity_iint_cache *iint; 168 struct integrity_iint_cache *iint;
169 struct ima_template_desc *template_desc = ima_template_desc_current();
147 char *pathbuf = NULL; 170 char *pathbuf = NULL;
148 const char *pathname = NULL; 171 const char *pathname = NULL;
149 int rc = -ENOMEM, action, must_appraise, _func; 172 int rc = -ENOMEM, action, must_appraise, _func;
173 struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL;
174 int xattr_len = 0;
150 175
151 if (!ima_initialized || !S_ISREG(inode->i_mode)) 176 if (!ima_initialized || !S_ISREG(inode->i_mode))
152 return 0; 177 return 0;
@@ -185,7 +210,13 @@ static int process_measurement(struct file *file, const char *filename,
185 goto out_digsig; 210 goto out_digsig;
186 } 211 }
187 212
188 rc = ima_collect_measurement(iint, file); 213 if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) {
214 if (action & IMA_APPRAISE_SUBMASK)
215 xattr_ptr = &xattr_value;
216 } else
217 xattr_ptr = &xattr_value;
218
219 rc = ima_collect_measurement(iint, file, xattr_ptr, &xattr_len);
189 if (rc != 0) 220 if (rc != 0)
190 goto out_digsig; 221 goto out_digsig;
191 222
@@ -194,9 +225,11 @@ static int process_measurement(struct file *file, const char *filename,
194 pathname = (const char *)file->f_dentry->d_name.name; 225 pathname = (const char *)file->f_dentry->d_name.name;
195 226
196 if (action & IMA_MEASURE) 227 if (action & IMA_MEASURE)
197 ima_store_measurement(iint, file, pathname); 228 ima_store_measurement(iint, file, pathname,
229 xattr_value, xattr_len);
198 if (action & IMA_APPRAISE_SUBMASK) 230 if (action & IMA_APPRAISE_SUBMASK)
199 rc = ima_appraise_measurement(_func, iint, file, pathname); 231 rc = ima_appraise_measurement(_func, iint, file, pathname,
232 xattr_value, xattr_len);
200 if (action & IMA_AUDIT) 233 if (action & IMA_AUDIT)
201 ima_audit_measurement(iint, pathname); 234 ima_audit_measurement(iint, pathname);
202 kfree(pathbuf); 235 kfree(pathbuf);
@@ -205,6 +238,7 @@ out_digsig:
205 rc = -EACCES; 238 rc = -EACCES;
206out: 239out:
207 mutex_unlock(&inode->i_mutex); 240 mutex_unlock(&inode->i_mutex);
241 kfree(xattr_value);
208 if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE)) 242 if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE))
209 return -EACCES; 243 return -EACCES;
210 return 0; 244 return 0;
@@ -244,9 +278,9 @@ int ima_file_mmap(struct file *file, unsigned long prot)
244int ima_bprm_check(struct linux_binprm *bprm) 278int ima_bprm_check(struct linux_binprm *bprm)
245{ 279{
246 return process_measurement(bprm->file, 280 return process_measurement(bprm->file,
247 (strcmp(bprm->filename, bprm->interp) == 0) ? 281 (strcmp(bprm->filename, bprm->interp) == 0) ?
248 bprm->filename : bprm->interp, 282 bprm->filename : bprm->interp,
249 MAY_EXEC, BPRM_CHECK); 283 MAY_EXEC, BPRM_CHECK);
250} 284}
251 285
252/** 286/**
@@ -263,8 +297,8 @@ int ima_file_check(struct file *file, int mask)
263{ 297{
264 ima_rdwr_violation_check(file); 298 ima_rdwr_violation_check(file);
265 return process_measurement(file, NULL, 299 return process_measurement(file, NULL,
266 mask & (MAY_READ | MAY_WRITE | MAY_EXEC), 300 mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
267 FILE_CHECK); 301 FILE_CHECK);
268} 302}
269EXPORT_SYMBOL_GPL(ima_file_check); 303EXPORT_SYMBOL_GPL(ima_file_check);
270 304
@@ -294,6 +328,7 @@ static int __init init_ima(void)
294{ 328{
295 int error; 329 int error;
296 330
331 hash_setup(CONFIG_IMA_DEFAULT_HASH);
297 error = ima_init(); 332 error = ima_init();
298 if (!error) 333 if (!error)
299 ima_initialized = 1; 334 ima_initialized = 1;
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 399433ad614e..a9c3d3cd1990 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -73,7 +73,6 @@ static struct ima_rule_entry default_rules[] = {
73 {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC}, 73 {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC},
74 {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, 74 {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC},
75 {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC}, 75 {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC},
76 {.action = DONT_MEASURE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC},
77 {.action = DONT_MEASURE,.fsmagic = DEVPTS_SUPER_MAGIC,.flags = IMA_FSMAGIC}, 76 {.action = DONT_MEASURE,.fsmagic = DEVPTS_SUPER_MAGIC,.flags = IMA_FSMAGIC},
78 {.action = DONT_MEASURE,.fsmagic = BINFMTFS_MAGIC,.flags = IMA_FSMAGIC}, 77 {.action = DONT_MEASURE,.fsmagic = BINFMTFS_MAGIC,.flags = IMA_FSMAGIC},
79 {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC}, 78 {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC},
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index ff63fe00c195..d85e99761f4f 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -50,7 +50,7 @@ static struct ima_queue_entry *ima_lookup_digest_entry(u8 *digest_value)
50 key = ima_hash_key(digest_value); 50 key = ima_hash_key(digest_value);
51 rcu_read_lock(); 51 rcu_read_lock();
52 hlist_for_each_entry_rcu(qe, &ima_htable.queue[key], hnext) { 52 hlist_for_each_entry_rcu(qe, &ima_htable.queue[key], hnext) {
53 rc = memcmp(qe->entry->digest, digest_value, IMA_DIGEST_SIZE); 53 rc = memcmp(qe->entry->digest, digest_value, TPM_DIGEST_SIZE);
54 if (rc == 0) { 54 if (rc == 0) {
55 ret = qe; 55 ret = qe;
56 break; 56 break;
@@ -104,9 +104,10 @@ static int ima_pcr_extend(const u8 *hash)
104 * and extend the pcr. 104 * and extend the pcr.
105 */ 105 */
106int ima_add_template_entry(struct ima_template_entry *entry, int violation, 106int ima_add_template_entry(struct ima_template_entry *entry, int violation,
107 const char *op, struct inode *inode) 107 const char *op, struct inode *inode,
108 const unsigned char *filename)
108{ 109{
109 u8 digest[IMA_DIGEST_SIZE]; 110 u8 digest[TPM_DIGEST_SIZE];
110 const char *audit_cause = "hash_added"; 111 const char *audit_cause = "hash_added";
111 char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX]; 112 char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX];
112 int audit_info = 1; 113 int audit_info = 1;
@@ -141,8 +142,7 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
141 } 142 }
142out: 143out:
143 mutex_unlock(&ima_extend_list_mutex); 144 mutex_unlock(&ima_extend_list_mutex);
144 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, 145 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
145 entry->template.file_name,
146 op, audit_cause, result, audit_info); 146 op, audit_cause, result, audit_info);
147 return result; 147 return result;
148} 148}
diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
new file mode 100644
index 000000000000..635695f6a185
--- /dev/null
+++ b/security/integrity/ima/ima_template.c
@@ -0,0 +1,187 @@
1/*
2 * Copyright (C) 2013 Politecnico di Torino, Italy
3 * TORSEC group -- http://security.polito.it
4 *
5 * Author: Roberto Sassu <roberto.sassu@polito.it>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2 of the
10 * License.
11 *
12 * File: ima_template.c
13 * Helpers to manage template descriptors.
14 */
15#include <crypto/hash_info.h>
16
17#include "ima.h"
18#include "ima_template_lib.h"
19
20static struct ima_template_desc defined_templates[] = {
21 {.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT},
22 {.name = "ima-ng",.fmt = "d-ng|n-ng"},
23 {.name = "ima-sig",.fmt = "d-ng|n-ng|sig"},
24};
25
26static struct ima_template_field supported_fields[] = {
27 {.field_id = "d",.field_init = ima_eventdigest_init,
28 .field_show = ima_show_template_digest},
29 {.field_id = "n",.field_init = ima_eventname_init,
30 .field_show = ima_show_template_string},
31 {.field_id = "d-ng",.field_init = ima_eventdigest_ng_init,
32 .field_show = ima_show_template_digest_ng},
33 {.field_id = "n-ng",.field_init = ima_eventname_ng_init,
34 .field_show = ima_show_template_string},
35 {.field_id = "sig",.field_init = ima_eventsig_init,
36 .field_show = ima_show_template_sig},
37};
38
39static struct ima_template_desc *ima_template;
40static struct ima_template_desc *lookup_template_desc(const char *name);
41
42static int __init ima_template_setup(char *str)
43{
44 struct ima_template_desc *template_desc;
45 int template_len = strlen(str);
46
47 /*
48 * Verify that a template with the supplied name exists.
49 * If not, use CONFIG_IMA_DEFAULT_TEMPLATE.
50 */
51 template_desc = lookup_template_desc(str);
52 if (!template_desc)
53 return 1;
54
55 /*
56 * Verify whether the current hash algorithm is supported
57 * by the 'ima' template.
58 */
59 if (template_len == 3 && strcmp(str, IMA_TEMPLATE_IMA_NAME) == 0 &&
60 ima_hash_algo != HASH_ALGO_SHA1 && ima_hash_algo != HASH_ALGO_MD5) {
61 pr_err("IMA: template does not support hash alg\n");
62 return 1;
63 }
64
65 ima_template = template_desc;
66 return 1;
67}
68__setup("ima_template=", ima_template_setup);
69
70static struct ima_template_desc *lookup_template_desc(const char *name)
71{
72 int i;
73
74 for (i = 0; i < ARRAY_SIZE(defined_templates); i++) {
75 if (strcmp(defined_templates[i].name, name) == 0)
76 return defined_templates + i;
77 }
78
79 return NULL;
80}
81
82static struct ima_template_field *lookup_template_field(const char *field_id)
83{
84 int i;
85
86 for (i = 0; i < ARRAY_SIZE(supported_fields); i++)
87 if (strncmp(supported_fields[i].field_id, field_id,
88 IMA_TEMPLATE_FIELD_ID_MAX_LEN) == 0)
89 return &supported_fields[i];
90 return NULL;
91}
92
93static int template_fmt_size(const char *template_fmt)
94{
95 char c;
96 int template_fmt_len = strlen(template_fmt);
97 int i = 0, j = 0;
98
99 while (i < template_fmt_len) {
100 c = template_fmt[i];
101 if (c == '|')
102 j++;
103 i++;
104 }
105
106 return j + 1;
107}
108
109static int template_desc_init_fields(const char *template_fmt,
110 struct ima_template_field ***fields,
111 int *num_fields)
112{
113 char *c, *template_fmt_copy, *template_fmt_ptr;
114 int template_num_fields = template_fmt_size(template_fmt);
115 int i, result = 0;
116
117 if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX)
118 return -EINVAL;
119
120 /* copying is needed as strsep() modifies the original buffer */
121 template_fmt_copy = kstrdup(template_fmt, GFP_KERNEL);
122 if (template_fmt_copy == NULL)
123 return -ENOMEM;
124
125 *fields = kzalloc(template_num_fields * sizeof(*fields), GFP_KERNEL);
126 if (*fields == NULL) {
127 result = -ENOMEM;
128 goto out;
129 }
130
131 template_fmt_ptr = template_fmt_copy;
132 for (i = 0; (c = strsep(&template_fmt_ptr, "|")) != NULL &&
133 i < template_num_fields; i++) {
134 struct ima_template_field *f = lookup_template_field(c);
135
136 if (!f) {
137 result = -ENOENT;
138 goto out;
139 }
140 (*fields)[i] = f;
141 }
142 *num_fields = i;
143out:
144 if (result < 0) {
145 kfree(*fields);
146 *fields = NULL;
147 }
148 kfree(template_fmt_copy);
149 return result;
150}
151
152static int init_defined_templates(void)
153{
154 int i = 0;
155 int result = 0;
156
157 /* Init defined templates. */
158 for (i = 0; i < ARRAY_SIZE(defined_templates); i++) {
159 struct ima_template_desc *template = &defined_templates[i];
160
161 result = template_desc_init_fields(template->fmt,
162 &(template->fields),
163 &(template->num_fields));
164 if (result < 0)
165 return result;
166 }
167 return result;
168}
169
170struct ima_template_desc *ima_template_desc_current(void)
171{
172 if (!ima_template)
173 ima_template =
174 lookup_template_desc(CONFIG_IMA_DEFAULT_TEMPLATE);
175 return ima_template;
176}
177
178int ima_init_template(void)
179{
180 int result;
181
182 result = init_defined_templates();
183 if (result < 0)
184 return result;
185
186 return 0;
187}
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
new file mode 100644
index 000000000000..c38adcc910fb
--- /dev/null
+++ b/security/integrity/ima/ima_template_lib.c
@@ -0,0 +1,351 @@
1/*
2 * Copyright (C) 2013 Politecnico di Torino, Italy
3 * TORSEC group -- http://security.polito.it
4 *
5 * Author: Roberto Sassu <roberto.sassu@polito.it>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2 of the
10 * License.
11 *
12 * File: ima_template_lib.c
13 * Library of supported template fields.
14 */
15#include <crypto/hash_info.h>
16
17#include "ima_template_lib.h"
18
19static bool ima_template_hash_algo_allowed(u8 algo)
20{
21 if (algo == HASH_ALGO_SHA1 || algo == HASH_ALGO_MD5)
22 return true;
23
24 return false;
25}
26
27enum data_formats {
28 DATA_FMT_DIGEST = 0,
29 DATA_FMT_DIGEST_WITH_ALGO,
30 DATA_FMT_EVENT_NAME,
31 DATA_FMT_STRING,
32 DATA_FMT_HEX
33};
34
35static int ima_write_template_field_data(const void *data, const u32 datalen,
36 enum data_formats datafmt,
37 struct ima_field_data *field_data)
38{
39 u8 *buf, *buf_ptr;
40 u32 buflen;
41
42 switch (datafmt) {
43 case DATA_FMT_EVENT_NAME:
44 buflen = IMA_EVENT_NAME_LEN_MAX + 1;
45 break;
46 case DATA_FMT_STRING:
47 buflen = datalen + 1;
48 break;
49 default:
50 buflen = datalen;
51 }
52
53 buf = kzalloc(buflen, GFP_KERNEL);
54 if (!buf)
55 return -ENOMEM;
56
57 memcpy(buf, data, datalen);
58
59 /*
60 * Replace all space characters with underscore for event names and
61 * strings. This avoid that, during the parsing of a measurements list,
62 * filenames with spaces or that end with the suffix ' (deleted)' are
63 * split into multiple template fields (the space is the delimitator
64 * character for measurements lists in ASCII format).
65 */
66 if (datafmt == DATA_FMT_EVENT_NAME || datafmt == DATA_FMT_STRING) {
67 for (buf_ptr = buf; buf_ptr - buf < datalen; buf_ptr++)
68 if (*buf_ptr == ' ')
69 *buf_ptr = '_';
70 }
71
72 field_data->data = buf;
73 field_data->len = buflen;
74 return 0;
75}
76
77static void ima_show_template_data_ascii(struct seq_file *m,
78 enum ima_show_type show,
79 enum data_formats datafmt,
80 struct ima_field_data *field_data)
81{
82 u8 *buf_ptr = field_data->data, buflen = field_data->len;
83
84 switch (datafmt) {
85 case DATA_FMT_DIGEST_WITH_ALGO:
86 buf_ptr = strnchr(field_data->data, buflen, ':');
87 if (buf_ptr != field_data->data)
88 seq_printf(m, "%s", field_data->data);
89
90 /* skip ':' and '\0' */
91 buf_ptr += 2;
92 buflen -= buf_ptr - field_data->data;
93 case DATA_FMT_DIGEST:
94 case DATA_FMT_HEX:
95 if (!buflen)
96 break;
97 ima_print_digest(m, buf_ptr, buflen);
98 break;
99 case DATA_FMT_STRING:
100 seq_printf(m, "%s", buf_ptr);
101 break;
102 default:
103 break;
104 }
105}
106
107static void ima_show_template_data_binary(struct seq_file *m,
108 enum ima_show_type show,
109 enum data_formats datafmt,
110 struct ima_field_data *field_data)
111{
112 if (show != IMA_SHOW_BINARY_NO_FIELD_LEN)
113 ima_putc(m, &field_data->len, sizeof(u32));
114
115 if (!field_data->len)
116 return;
117
118 ima_putc(m, field_data->data, field_data->len);
119}
120
121static void ima_show_template_field_data(struct seq_file *m,
122 enum ima_show_type show,
123 enum data_formats datafmt,
124 struct ima_field_data *field_data)
125{
126 switch (show) {
127 case IMA_SHOW_ASCII:
128 ima_show_template_data_ascii(m, show, datafmt, field_data);
129 break;
130 case IMA_SHOW_BINARY:
131 case IMA_SHOW_BINARY_NO_FIELD_LEN:
132 ima_show_template_data_binary(m, show, datafmt, field_data);
133 break;
134 default:
135 break;
136 }
137}
138
139void ima_show_template_digest(struct seq_file *m, enum ima_show_type show,
140 struct ima_field_data *field_data)
141{
142 ima_show_template_field_data(m, show, DATA_FMT_DIGEST, field_data);
143}
144
145void ima_show_template_digest_ng(struct seq_file *m, enum ima_show_type show,
146 struct ima_field_data *field_data)
147{
148 ima_show_template_field_data(m, show, DATA_FMT_DIGEST_WITH_ALGO,
149 field_data);
150}
151
152void ima_show_template_string(struct seq_file *m, enum ima_show_type show,
153 struct ima_field_data *field_data)
154{
155 ima_show_template_field_data(m, show, DATA_FMT_STRING, field_data);
156}
157
158void ima_show_template_sig(struct seq_file *m, enum ima_show_type show,
159 struct ima_field_data *field_data)
160{
161 ima_show_template_field_data(m, show, DATA_FMT_HEX, field_data);
162}
163
164static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo,
165 struct ima_field_data *field_data,
166 bool size_limit)
167{
168 /*
169 * digest formats:
170 * - DATA_FMT_DIGEST: digest
171 * - DATA_FMT_DIGEST_WITH_ALGO: [<hash algo>] + ':' + '\0' + digest,
172 * where <hash algo> is provided if the hash algoritm is not
173 * SHA1 or MD5
174 */
175 u8 buffer[CRYPTO_MAX_ALG_NAME + 2 + IMA_MAX_DIGEST_SIZE] = { 0 };
176 enum data_formats fmt = DATA_FMT_DIGEST;
177 u32 offset = 0;
178
179 if (!size_limit) {
180 fmt = DATA_FMT_DIGEST_WITH_ALGO;
181 if (hash_algo < HASH_ALGO__LAST)
182 offset += snprintf(buffer, CRYPTO_MAX_ALG_NAME + 1,
183 "%s", hash_algo_name[hash_algo]);
184 buffer[offset] = ':';
185 offset += 2;
186 }
187
188 if (digest)
189 memcpy(buffer + offset, digest, digestsize);
190 else
191 /*
192 * If digest is NULL, the event being recorded is a violation.
193 * Make room for the digest by increasing the offset of
194 * IMA_DIGEST_SIZE.
195 */
196 offset += IMA_DIGEST_SIZE;
197
198 return ima_write_template_field_data(buffer, offset + digestsize,
199 fmt, field_data);
200}
201
202/*
203 * This function writes the digest of an event (with size limit).
204 */
205int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
206 const unsigned char *filename,
207 struct evm_ima_xattr_data *xattr_value, int xattr_len,
208 struct ima_field_data *field_data)
209{
210 struct {
211 struct ima_digest_data hdr;
212 char digest[IMA_MAX_DIGEST_SIZE];
213 } hash;
214 u8 *cur_digest = NULL;
215 u32 cur_digestsize = 0;
216 struct inode *inode;
217 int result;
218
219 memset(&hash, 0, sizeof(hash));
220
221 if (!iint) /* recording a violation. */
222 goto out;
223
224 if (ima_template_hash_algo_allowed(iint->ima_hash->algo)) {
225 cur_digest = iint->ima_hash->digest;
226 cur_digestsize = iint->ima_hash->length;
227 goto out;
228 }
229
230 if (!file) /* missing info to re-calculate the digest */
231 return -EINVAL;
232
233 inode = file_inode(file);
234 hash.hdr.algo = ima_template_hash_algo_allowed(ima_hash_algo) ?
235 ima_hash_algo : HASH_ALGO_SHA1;
236 result = ima_calc_file_hash(file, &hash.hdr);
237 if (result) {
238 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
239 filename, "collect_data",
240 "failed", result, 0);
241 return result;
242 }
243 cur_digest = hash.hdr.digest;
244 cur_digestsize = hash.hdr.length;
245out:
246 return ima_eventdigest_init_common(cur_digest, cur_digestsize, -1,
247 field_data, true);
248}
249
250/*
251 * This function writes the digest of an event (without size limit).
252 */
253int ima_eventdigest_ng_init(struct integrity_iint_cache *iint,
254 struct file *file, const unsigned char *filename,
255 struct evm_ima_xattr_data *xattr_value,
256 int xattr_len, struct ima_field_data *field_data)
257{
258 u8 *cur_digest = NULL, hash_algo = HASH_ALGO__LAST;
259 u32 cur_digestsize = 0;
260
261 /* If iint is NULL, we are recording a violation. */
262 if (!iint)
263 goto out;
264
265 cur_digest = iint->ima_hash->digest;
266 cur_digestsize = iint->ima_hash->length;
267
268 hash_algo = iint->ima_hash->algo;
269out:
270 return ima_eventdigest_init_common(cur_digest, cur_digestsize,
271 hash_algo, field_data, false);
272}
273
274static int ima_eventname_init_common(struct integrity_iint_cache *iint,
275 struct file *file,
276 const unsigned char *filename,
277 struct ima_field_data *field_data,
278 bool size_limit)
279{
280 const char *cur_filename = NULL;
281 u32 cur_filename_len = 0;
282 enum data_formats fmt = size_limit ?
283 DATA_FMT_EVENT_NAME : DATA_FMT_STRING;
284
285 BUG_ON(filename == NULL && file == NULL);
286
287 if (filename) {
288 cur_filename = filename;
289 cur_filename_len = strlen(filename);
290
291 if (!size_limit || cur_filename_len <= IMA_EVENT_NAME_LEN_MAX)
292 goto out;
293 }
294
295 if (file) {
296 cur_filename = file->f_dentry->d_name.name;
297 cur_filename_len = strlen(cur_filename);
298 } else
299 /*
300 * Truncate filename if the latter is too long and
301 * the file descriptor is not available.
302 */
303 cur_filename_len = IMA_EVENT_NAME_LEN_MAX;
304out:
305 return ima_write_template_field_data(cur_filename, cur_filename_len,
306 fmt, field_data);
307}
308
309/*
310 * This function writes the name of an event (with size limit).
311 */
312int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file,
313 const unsigned char *filename,
314 struct evm_ima_xattr_data *xattr_value, int xattr_len,
315 struct ima_field_data *field_data)
316{
317 return ima_eventname_init_common(iint, file, filename,
318 field_data, true);
319}
320
321/*
322 * This function writes the name of an event (without size limit).
323 */
324int ima_eventname_ng_init(struct integrity_iint_cache *iint, struct file *file,
325 const unsigned char *filename,
326 struct evm_ima_xattr_data *xattr_value, int xattr_len,
327 struct ima_field_data *field_data)
328{
329 return ima_eventname_init_common(iint, file, filename,
330 field_data, false);
331}
332
333/*
334 * ima_eventsig_init - include the file signature as part of the template data
335 */
336int ima_eventsig_init(struct integrity_iint_cache *iint, struct file *file,
337 const unsigned char *filename,
338 struct evm_ima_xattr_data *xattr_value, int xattr_len,
339 struct ima_field_data *field_data)
340{
341 enum data_formats fmt = DATA_FMT_HEX;
342 int rc = 0;
343
344 if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG))
345 goto out;
346
347 rc = ima_write_template_field_data(xattr_value, xattr_len, fmt,
348 field_data);
349out:
350 return rc;
351}
diff --git a/security/integrity/ima/ima_template_lib.h b/security/integrity/ima/ima_template_lib.h
new file mode 100644
index 000000000000..63f6b52cb1c2
--- /dev/null
+++ b/security/integrity/ima/ima_template_lib.h
@@ -0,0 +1,49 @@
1/*
2 * Copyright (C) 2013 Politecnico di Torino, Italy
3 * TORSEC group -- http://security.polito.it
4 *
5 * Author: Roberto Sassu <roberto.sassu@polito.it>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2 of the
10 * License.
11 *
12 * File: ima_template_lib.h
13 * Header for the library of supported template fields.
14 */
15#ifndef __LINUX_IMA_TEMPLATE_LIB_H
16#define __LINUX_IMA_TEMPLATE_LIB_H
17
18#include <linux/seq_file.h>
19#include "ima.h"
20
21void ima_show_template_digest(struct seq_file *m, enum ima_show_type show,
22 struct ima_field_data *field_data);
23void ima_show_template_digest_ng(struct seq_file *m, enum ima_show_type show,
24 struct ima_field_data *field_data);
25void ima_show_template_string(struct seq_file *m, enum ima_show_type show,
26 struct ima_field_data *field_data);
27void ima_show_template_sig(struct seq_file *m, enum ima_show_type show,
28 struct ima_field_data *field_data);
29int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
30 const unsigned char *filename,
31 struct evm_ima_xattr_data *xattr_value, int xattr_len,
32 struct ima_field_data *field_data);
33int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file,
34 const unsigned char *filename,
35 struct evm_ima_xattr_data *xattr_value, int xattr_len,
36 struct ima_field_data *field_data);
37int ima_eventdigest_ng_init(struct integrity_iint_cache *iint,
38 struct file *file, const unsigned char *filename,
39 struct evm_ima_xattr_data *xattr_value,
40 int xattr_len, struct ima_field_data *field_data);
41int ima_eventname_ng_init(struct integrity_iint_cache *iint, struct file *file,
42 const unsigned char *filename,
43 struct evm_ima_xattr_data *xattr_value, int xattr_len,
44 struct ima_field_data *field_data);
45int ima_eventsig_init(struct integrity_iint_cache *iint, struct file *file,
46 const unsigned char *filename,
47 struct evm_ima_xattr_data *xattr_value, int xattr_len,
48 struct ima_field_data *field_data);
49#endif /* __LINUX_IMA_TEMPLATE_LIB_H */