diff options
author | Roberto Sassu <rsassu@suse.de> | 2015-04-11 11:09:50 -0400 |
---|---|---|
committer | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2015-05-21 13:59:28 -0400 |
commit | 23b5741932ca44856762fa24cc7e01307ab8af1f (patch) | |
tree | 0885bc7def9719d65c843b4b498deccd6c56dc2c /security/integrity | |
parent | 9d03a721a3a4a5120de790a0e67dc324c2ed9184 (diff) |
ima: wrap event related data to the new ima_event_data structure
All event related data has been wrapped into the new 'ima_event_data'
structure. The main benefit of this patch is that a new information
can be made available to template fields initialization functions
by simply adding a new field to the new structure instead of modifying
the definition of those functions.
Changelog:
- v2:
- f_dentry replaced with f_path.dentry (Roberto Sassu)
- removed declaration of temporary variables in template field functions
when possible (suggested by Dmitry Kasatkin)
Signed-off-by: Roberto Sassu <rsassu@suse.de>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Diffstat (limited to 'security/integrity')
-rw-r--r-- | security/integrity/ima/ima.h | 25 | ||||
-rw-r--r-- | security/integrity/ima/ima_api.c | 18 | ||||
-rw-r--r-- | security/integrity/ima/ima_init.c | 5 | ||||
-rw-r--r-- | security/integrity/ima/ima_template_lib.c | 70 | ||||
-rw-r--r-- | security/integrity/ima/ima_template_lib.h | 22 |
5 files changed, 61 insertions, 79 deletions
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 8ee997dff139..e13ae5466bf2 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h | |||
@@ -52,6 +52,15 @@ extern int ima_used_chip; | |||
52 | extern int ima_hash_algo; | 52 | extern int ima_hash_algo; |
53 | extern int ima_appraise; | 53 | extern int ima_appraise; |
54 | 54 | ||
55 | /* IMA event related data */ | ||
56 | struct ima_event_data { | ||
57 | struct integrity_iint_cache *iint; | ||
58 | struct file *file; | ||
59 | const unsigned char *filename; | ||
60 | struct evm_ima_xattr_data *xattr_value; | ||
61 | int xattr_len; | ||
62 | }; | ||
63 | |||
55 | /* IMA template field data definition */ | 64 | /* IMA template field data definition */ |
56 | struct ima_field_data { | 65 | struct ima_field_data { |
57 | u8 *data; | 66 | u8 *data; |
@@ -61,12 +70,10 @@ struct ima_field_data { | |||
61 | /* IMA template field definition */ | 70 | /* IMA template field definition */ |
62 | struct ima_template_field { | 71 | struct ima_template_field { |
63 | const char field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN]; | 72 | const char field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN]; |
64 | int (*field_init) (struct integrity_iint_cache *iint, struct file *file, | 73 | int (*field_init)(struct ima_event_data *event_data, |
65 | const unsigned char *filename, | 74 | struct ima_field_data *field_data); |
66 | struct evm_ima_xattr_data *xattr_value, | 75 | void (*field_show)(struct seq_file *m, enum ima_show_type show, |
67 | int xattr_len, struct ima_field_data *field_data); | 76 | struct ima_field_data *field_data); |
68 | void (*field_show) (struct seq_file *m, enum ima_show_type show, | ||
69 | struct ima_field_data *field_data); | ||
70 | }; | 77 | }; |
71 | 78 | ||
72 | /* IMA template descriptor definition */ | 79 | /* IMA template descriptor definition */ |
@@ -140,10 +147,8 @@ void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, | |||
140 | int xattr_len); | 147 | int xattr_len); |
141 | void ima_audit_measurement(struct integrity_iint_cache *iint, | 148 | void ima_audit_measurement(struct integrity_iint_cache *iint, |
142 | const unsigned char *filename); | 149 | const unsigned char *filename); |
143 | int ima_alloc_init_template(struct integrity_iint_cache *iint, | 150 | int ima_alloc_init_template(struct ima_event_data *event_data, |
144 | struct file *file, const unsigned char *filename, | 151 | struct ima_template_entry **entry); |
145 | struct evm_ima_xattr_data *xattr_value, | ||
146 | int xattr_len, struct ima_template_entry **entry); | ||
147 | int ima_store_template(struct ima_template_entry *entry, int violation, | 152 | int ima_store_template(struct ima_template_entry *entry, int violation, |
148 | struct inode *inode, const unsigned char *filename); | 153 | struct inode *inode, const unsigned char *filename); |
149 | void ima_free_template_entry(struct ima_template_entry *entry); | 154 | void ima_free_template_entry(struct ima_template_entry *entry); |
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index b8a27c5052d4..5865ea2a2777 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c | |||
@@ -37,10 +37,8 @@ void ima_free_template_entry(struct ima_template_entry *entry) | |||
37 | /* | 37 | /* |
38 | * ima_alloc_init_template - create and initialize a new template entry | 38 | * ima_alloc_init_template - create and initialize a new template entry |
39 | */ | 39 | */ |
40 | int ima_alloc_init_template(struct integrity_iint_cache *iint, | 40 | int ima_alloc_init_template(struct ima_event_data *event_data, |
41 | struct file *file, const unsigned char *filename, | 41 | struct ima_template_entry **entry) |
42 | struct evm_ima_xattr_data *xattr_value, | ||
43 | int xattr_len, struct ima_template_entry **entry) | ||
44 | { | 42 | { |
45 | struct ima_template_desc *template_desc = ima_template_desc_current(); | 43 | struct ima_template_desc *template_desc = ima_template_desc_current(); |
46 | int i, result = 0; | 44 | int i, result = 0; |
@@ -55,8 +53,7 @@ int ima_alloc_init_template(struct integrity_iint_cache *iint, | |||
55 | struct ima_template_field *field = template_desc->fields[i]; | 53 | struct ima_template_field *field = template_desc->fields[i]; |
56 | u32 len; | 54 | u32 len; |
57 | 55 | ||
58 | result = field->field_init(iint, file, filename, | 56 | result = field->field_init(event_data, |
59 | xattr_value, xattr_len, | ||
60 | &((*entry)->template_data[i])); | 57 | &((*entry)->template_data[i])); |
61 | if (result != 0) | 58 | if (result != 0) |
62 | goto out; | 59 | goto out; |
@@ -133,14 +130,14 @@ void ima_add_violation(struct file *file, const unsigned char *filename, | |||
133 | { | 130 | { |
134 | struct ima_template_entry *entry; | 131 | struct ima_template_entry *entry; |
135 | struct inode *inode = file_inode(file); | 132 | struct inode *inode = file_inode(file); |
133 | struct ima_event_data event_data = {NULL, file, filename, NULL, 0}; | ||
136 | int violation = 1; | 134 | int violation = 1; |
137 | int result; | 135 | int result; |
138 | 136 | ||
139 | /* can overflow, only indicator */ | 137 | /* can overflow, only indicator */ |
140 | atomic_long_inc(&ima_htable.violations); | 138 | atomic_long_inc(&ima_htable.violations); |
141 | 139 | ||
142 | result = ima_alloc_init_template(NULL, file, filename, | 140 | result = ima_alloc_init_template(&event_data, &entry); |
143 | NULL, 0, &entry); | ||
144 | if (result < 0) { | 141 | if (result < 0) { |
145 | result = -ENOMEM; | 142 | result = -ENOMEM; |
146 | goto err_out; | 143 | goto err_out; |
@@ -267,13 +264,14 @@ void ima_store_measurement(struct integrity_iint_cache *iint, | |||
267 | int result = -ENOMEM; | 264 | int result = -ENOMEM; |
268 | struct inode *inode = file_inode(file); | 265 | struct inode *inode = file_inode(file); |
269 | struct ima_template_entry *entry; | 266 | struct ima_template_entry *entry; |
267 | struct ima_event_data event_data = {iint, file, filename, | ||
268 | xattr_value, xattr_len}; | ||
270 | int violation = 0; | 269 | int violation = 0; |
271 | 270 | ||
272 | if (iint->flags & IMA_MEASURED) | 271 | if (iint->flags & IMA_MEASURED) |
273 | return; | 272 | return; |
274 | 273 | ||
275 | result = ima_alloc_init_template(iint, file, filename, | 274 | result = ima_alloc_init_template(&event_data, &entry); |
276 | xattr_value, xattr_len, &entry); | ||
277 | if (result < 0) { | 275 | if (result < 0) { |
278 | integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, | 276 | integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, |
279 | op, audit_cause, result, 0); | 277 | op, audit_cause, result, 0); |
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index 0f4cffd76070..2c668370a438 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c | |||
@@ -49,6 +49,8 @@ static int __init ima_add_boot_aggregate(void) | |||
49 | const char *audit_cause = "ENOMEM"; | 49 | const char *audit_cause = "ENOMEM"; |
50 | struct ima_template_entry *entry; | 50 | struct ima_template_entry *entry; |
51 | struct integrity_iint_cache tmp_iint, *iint = &tmp_iint; | 51 | struct integrity_iint_cache tmp_iint, *iint = &tmp_iint; |
52 | struct ima_event_data event_data = {iint, NULL, boot_aggregate_name, | ||
53 | NULL, 0}; | ||
52 | int result = -ENOMEM; | 54 | int result = -ENOMEM; |
53 | int violation = 0; | 55 | int violation = 0; |
54 | struct { | 56 | struct { |
@@ -70,8 +72,7 @@ static int __init ima_add_boot_aggregate(void) | |||
70 | } | 72 | } |
71 | } | 73 | } |
72 | 74 | ||
73 | result = ima_alloc_init_template(iint, NULL, boot_aggregate_name, | 75 | result = ima_alloc_init_template(&event_data, &entry); |
74 | NULL, 0, &entry); | ||
75 | if (result < 0) { | 76 | if (result < 0) { |
76 | audit_cause = "alloc_entry"; | 77 | audit_cause = "alloc_entry"; |
77 | goto err_out; | 78 | goto err_out; |
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c index bcfc36cbde6a..67d513367aac 100644 --- a/security/integrity/ima/ima_template_lib.c +++ b/security/integrity/ima/ima_template_lib.c | |||
@@ -195,9 +195,7 @@ static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo, | |||
195 | /* | 195 | /* |
196 | * This function writes the digest of an event (with size limit). | 196 | * This function writes the digest of an event (with size limit). |
197 | */ | 197 | */ |
198 | int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file, | 198 | int ima_eventdigest_init(struct ima_event_data *event_data, |
199 | const unsigned char *filename, | ||
200 | struct evm_ima_xattr_data *xattr_value, int xattr_len, | ||
201 | struct ima_field_data *field_data) | 199 | struct ima_field_data *field_data) |
202 | { | 200 | { |
203 | struct { | 201 | struct { |
@@ -211,25 +209,25 @@ int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file, | |||
211 | 209 | ||
212 | memset(&hash, 0, sizeof(hash)); | 210 | memset(&hash, 0, sizeof(hash)); |
213 | 211 | ||
214 | if (!iint) /* recording a violation. */ | 212 | if (!event_data->iint) /* recording a violation. */ |
215 | goto out; | 213 | goto out; |
216 | 214 | ||
217 | if (ima_template_hash_algo_allowed(iint->ima_hash->algo)) { | 215 | if (ima_template_hash_algo_allowed(event_data->iint->ima_hash->algo)) { |
218 | cur_digest = iint->ima_hash->digest; | 216 | cur_digest = event_data->iint->ima_hash->digest; |
219 | cur_digestsize = iint->ima_hash->length; | 217 | cur_digestsize = event_data->iint->ima_hash->length; |
220 | goto out; | 218 | goto out; |
221 | } | 219 | } |
222 | 220 | ||
223 | if (!file) /* missing info to re-calculate the digest */ | 221 | if (!event_data->file) /* missing info to re-calculate the digest */ |
224 | return -EINVAL; | 222 | return -EINVAL; |
225 | 223 | ||
226 | inode = file_inode(file); | 224 | inode = file_inode(event_data->file); |
227 | hash.hdr.algo = ima_template_hash_algo_allowed(ima_hash_algo) ? | 225 | hash.hdr.algo = ima_template_hash_algo_allowed(ima_hash_algo) ? |
228 | ima_hash_algo : HASH_ALGO_SHA1; | 226 | ima_hash_algo : HASH_ALGO_SHA1; |
229 | result = ima_calc_file_hash(file, &hash.hdr); | 227 | result = ima_calc_file_hash(event_data->file, &hash.hdr); |
230 | if (result) { | 228 | if (result) { |
231 | integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, | 229 | integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, |
232 | filename, "collect_data", | 230 | event_data->filename, "collect_data", |
233 | "failed", result, 0); | 231 | "failed", result, 0); |
234 | return result; | 232 | return result; |
235 | } | 233 | } |
@@ -243,48 +241,44 @@ out: | |||
243 | /* | 241 | /* |
244 | * This function writes the digest of an event (without size limit). | 242 | * This function writes the digest of an event (without size limit). |
245 | */ | 243 | */ |
246 | int ima_eventdigest_ng_init(struct integrity_iint_cache *iint, | 244 | int ima_eventdigest_ng_init(struct ima_event_data *event_data, |
247 | struct file *file, const unsigned char *filename, | 245 | struct ima_field_data *field_data) |
248 | struct evm_ima_xattr_data *xattr_value, | ||
249 | int xattr_len, struct ima_field_data *field_data) | ||
250 | { | 246 | { |
251 | u8 *cur_digest = NULL, hash_algo = HASH_ALGO_SHA1; | 247 | u8 *cur_digest = NULL, hash_algo = HASH_ALGO_SHA1; |
252 | u32 cur_digestsize = 0; | 248 | u32 cur_digestsize = 0; |
253 | 249 | ||
254 | /* If iint is NULL, we are recording a violation. */ | 250 | /* If iint is NULL, we are recording a violation. */ |
255 | if (!iint) | 251 | if (!event_data->iint) |
256 | goto out; | 252 | goto out; |
257 | 253 | ||
258 | cur_digest = iint->ima_hash->digest; | 254 | cur_digest = event_data->iint->ima_hash->digest; |
259 | cur_digestsize = iint->ima_hash->length; | 255 | cur_digestsize = event_data->iint->ima_hash->length; |
260 | 256 | ||
261 | hash_algo = iint->ima_hash->algo; | 257 | hash_algo = event_data->iint->ima_hash->algo; |
262 | out: | 258 | out: |
263 | return ima_eventdigest_init_common(cur_digest, cur_digestsize, | 259 | return ima_eventdigest_init_common(cur_digest, cur_digestsize, |
264 | hash_algo, field_data); | 260 | hash_algo, field_data); |
265 | } | 261 | } |
266 | 262 | ||
267 | static int ima_eventname_init_common(struct integrity_iint_cache *iint, | 263 | static int ima_eventname_init_common(struct ima_event_data *event_data, |
268 | struct file *file, | ||
269 | const unsigned char *filename, | ||
270 | struct ima_field_data *field_data, | 264 | struct ima_field_data *field_data, |
271 | bool size_limit) | 265 | bool size_limit) |
272 | { | 266 | { |
273 | const char *cur_filename = NULL; | 267 | const char *cur_filename = NULL; |
274 | u32 cur_filename_len = 0; | 268 | u32 cur_filename_len = 0; |
275 | 269 | ||
276 | BUG_ON(filename == NULL && file == NULL); | 270 | BUG_ON(event_data->filename == NULL && event_data->file == NULL); |
277 | 271 | ||
278 | if (filename) { | 272 | if (event_data->filename) { |
279 | cur_filename = filename; | 273 | cur_filename = event_data->filename; |
280 | cur_filename_len = strlen(filename); | 274 | cur_filename_len = strlen(event_data->filename); |
281 | 275 | ||
282 | if (!size_limit || cur_filename_len <= IMA_EVENT_NAME_LEN_MAX) | 276 | if (!size_limit || cur_filename_len <= IMA_EVENT_NAME_LEN_MAX) |
283 | goto out; | 277 | goto out; |
284 | } | 278 | } |
285 | 279 | ||
286 | if (file) { | 280 | if (event_data->file) { |
287 | cur_filename = file->f_path.dentry->d_name.name; | 281 | cur_filename = event_data->file->f_path.dentry->d_name.name; |
288 | cur_filename_len = strlen(cur_filename); | 282 | cur_filename_len = strlen(cur_filename); |
289 | } else | 283 | } else |
290 | /* | 284 | /* |
@@ -300,36 +294,30 @@ out: | |||
300 | /* | 294 | /* |
301 | * This function writes the name of an event (with size limit). | 295 | * This function writes the name of an event (with size limit). |
302 | */ | 296 | */ |
303 | int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file, | 297 | int ima_eventname_init(struct ima_event_data *event_data, |
304 | const unsigned char *filename, | ||
305 | struct evm_ima_xattr_data *xattr_value, int xattr_len, | ||
306 | struct ima_field_data *field_data) | 298 | struct ima_field_data *field_data) |
307 | { | 299 | { |
308 | return ima_eventname_init_common(iint, file, filename, | 300 | return ima_eventname_init_common(event_data, field_data, true); |
309 | field_data, true); | ||
310 | } | 301 | } |
311 | 302 | ||
312 | /* | 303 | /* |
313 | * This function writes the name of an event (without size limit). | 304 | * This function writes the name of an event (without size limit). |
314 | */ | 305 | */ |
315 | int ima_eventname_ng_init(struct integrity_iint_cache *iint, struct file *file, | 306 | int ima_eventname_ng_init(struct ima_event_data *event_data, |
316 | const unsigned char *filename, | ||
317 | struct evm_ima_xattr_data *xattr_value, int xattr_len, | ||
318 | struct ima_field_data *field_data) | 307 | struct ima_field_data *field_data) |
319 | { | 308 | { |
320 | return ima_eventname_init_common(iint, file, filename, | 309 | return ima_eventname_init_common(event_data, field_data, false); |
321 | field_data, false); | ||
322 | } | 310 | } |
323 | 311 | ||
324 | /* | 312 | /* |
325 | * ima_eventsig_init - include the file signature as part of the template data | 313 | * ima_eventsig_init - include the file signature as part of the template data |
326 | */ | 314 | */ |
327 | int ima_eventsig_init(struct integrity_iint_cache *iint, struct file *file, | 315 | int ima_eventsig_init(struct ima_event_data *event_data, |
328 | const unsigned char *filename, | ||
329 | struct evm_ima_xattr_data *xattr_value, int xattr_len, | ||
330 | struct ima_field_data *field_data) | 316 | struct ima_field_data *field_data) |
331 | { | 317 | { |
332 | enum data_formats fmt = DATA_FMT_HEX; | 318 | enum data_formats fmt = DATA_FMT_HEX; |
319 | struct evm_ima_xattr_data *xattr_value = event_data->xattr_value; | ||
320 | int xattr_len = event_data->xattr_len; | ||
333 | int rc = 0; | 321 | int rc = 0; |
334 | 322 | ||
335 | if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG)) | 323 | if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG)) |
diff --git a/security/integrity/ima/ima_template_lib.h b/security/integrity/ima/ima_template_lib.h index 63f6b52cb1c2..c344530c1d69 100644 --- a/security/integrity/ima/ima_template_lib.h +++ b/security/integrity/ima/ima_template_lib.h | |||
@@ -26,24 +26,14 @@ void ima_show_template_string(struct seq_file *m, enum ima_show_type show, | |||
26 | struct ima_field_data *field_data); | 26 | struct ima_field_data *field_data); |
27 | void ima_show_template_sig(struct seq_file *m, enum ima_show_type show, | 27 | void ima_show_template_sig(struct seq_file *m, enum ima_show_type show, |
28 | struct ima_field_data *field_data); | 28 | struct ima_field_data *field_data); |
29 | int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file, | 29 | int ima_eventdigest_init(struct ima_event_data *event_data, |
30 | const unsigned char *filename, | ||
31 | struct evm_ima_xattr_data *xattr_value, int xattr_len, | ||
32 | struct ima_field_data *field_data); | 30 | struct ima_field_data *field_data); |
33 | int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file, | 31 | int ima_eventname_init(struct ima_event_data *event_data, |
34 | const unsigned char *filename, | ||
35 | struct evm_ima_xattr_data *xattr_value, int xattr_len, | ||
36 | struct ima_field_data *field_data); | 32 | struct ima_field_data *field_data); |
37 | int ima_eventdigest_ng_init(struct integrity_iint_cache *iint, | 33 | int ima_eventdigest_ng_init(struct ima_event_data *event_data, |
38 | struct file *file, const unsigned char *filename, | 34 | struct ima_field_data *field_data); |
39 | struct evm_ima_xattr_data *xattr_value, | 35 | int ima_eventname_ng_init(struct ima_event_data *event_data, |
40 | int xattr_len, struct ima_field_data *field_data); | ||
41 | int 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); | 36 | struct ima_field_data *field_data); |
45 | int ima_eventsig_init(struct integrity_iint_cache *iint, struct file *file, | 37 | int ima_eventsig_init(struct ima_event_data *event_data, |
46 | const unsigned char *filename, | ||
47 | struct evm_ima_xattr_data *xattr_value, int xattr_len, | ||
48 | struct ima_field_data *field_data); | 38 | struct ima_field_data *field_data); |
49 | #endif /* __LINUX_IMA_TEMPLATE_LIB_H */ | 39 | #endif /* __LINUX_IMA_TEMPLATE_LIB_H */ |