aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoberto Sassu <roberto.sassu@polito.it>2013-06-07 06:16:30 -0400
committerMimi Zohar <zohar@linux.vnet.ibm.com>2013-10-25 17:17:05 -0400
commit3ce1217d6cd5dfa82a9db5c2a999cc1bb01490d9 (patch)
tree4645a20eaa70b3dc5dd4654fa31a7cf132291fd5
parentadf53a778a0a5a5dc9103509da4a9719046e5310 (diff)
ima: define template fields library and new helpers
This patch defines a library containing two initial template fields, inode digest (d) and file name (n), the 'ima' template descriptor, whose format is 'd|n', and two helper functions, ima_write_template_field_data() and ima_show_template_field_data(). Changelog: - replace ima_eventname_init() parameter NULL checking with BUG_ON. (suggested by Mimi) - include "new template fields for inode digest (d) and file name (n)" definitions to fix a compiler warning. - Mimi - unnecessary to prefix static function names with 'ima_'. remove prefix to resolve Lindent formatting changes. - Mimi - abbreviated/removed inline comments - Mimi - always send the template field length - Mimi Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
-rw-r--r--security/integrity/ima/Makefile2
-rw-r--r--security/integrity/ima/ima.h5
-rw-r--r--security/integrity/ima/ima_fs.c4
-rw-r--r--security/integrity/ima/ima_template.c15
-rw-r--r--security/integrity/ima/ima_template_lib.c193
-rw-r--r--security/integrity/ima/ima_template_lib.h31
6 files changed, 242 insertions, 8 deletions
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index 7fe4ae37dbea..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 ima_template.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 c85718f1f623..e1f081d65dbf 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -39,6 +39,9 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
39#define IMA_TEMPLATE_FIELD_ID_MAX_LEN 16 39#define IMA_TEMPLATE_FIELD_ID_MAX_LEN 16
40#define IMA_TEMPLATE_NUM_FIELDS_MAX 15 40#define IMA_TEMPLATE_NUM_FIELDS_MAX 15
41 41
42#define IMA_TEMPLATE_IMA_NAME "ima"
43#define IMA_TEMPLATE_IMA_FMT "d|n"
44
42/* set during initialization */ 45/* set during initialization */
43extern int ima_initialized; 46extern int ima_initialized;
44extern int ima_used_chip; 47extern int ima_used_chip;
@@ -105,6 +108,8 @@ int __init ima_calc_boot_aggregate(struct ima_digest_data *hash);
105void ima_add_violation(struct file *file, const unsigned char *filename, 108void ima_add_violation(struct file *file, const unsigned char *filename,
106 const char *op, const char *cause); 109 const char *op, const char *cause);
107int ima_init_crypto(void); 110int ima_init_crypto(void);
111void ima_putc(struct seq_file *m, void *data, int datalen);
112void ima_print_digest(struct seq_file *m, u8 *digest, int size);
108 113
109int ima_init_template(void); 114int ima_init_template(void);
110 115
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index c35cfb5b3c5e..414862e1904b 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -99,7 +99,7 @@ static void ima_measurements_stop(struct seq_file *m, void *v)
99{ 99{
100} 100}
101 101
102static void ima_putc(struct seq_file *m, void *data, int datalen) 102void ima_putc(struct seq_file *m, void *data, int datalen)
103{ 103{
104 while (datalen--) 104 while (datalen--)
105 seq_putc(m, *(char *)data++); 105 seq_putc(m, *(char *)data++);
@@ -167,7 +167,7 @@ static const struct file_operations ima_measurements_ops = {
167 .release = seq_release, 167 .release = seq_release,
168}; 168};
169 169
170static void ima_print_digest(struct seq_file *m, u8 *digest, int size) 170void ima_print_digest(struct seq_file *m, u8 *digest, int size)
171{ 171{
172 int i; 172 int i;
173 173
diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
index 7e86783ccf51..810042264396 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -13,15 +13,20 @@
13 * Helpers to manage template descriptors. 13 * Helpers to manage template descriptors.
14 */ 14 */
15#include "ima.h" 15#include "ima.h"
16#include "ima_template_lib.h"
16 17
17static struct ima_template_desc defined_templates[] = { 18static struct ima_template_desc defined_templates[] = {
19 {.name = IMA_TEMPLATE_IMA_NAME,.fmt = IMA_TEMPLATE_IMA_FMT},
18}; 20};
19 21
20static struct ima_template_field supported_fields[] = { 22static struct ima_template_field supported_fields[] = {
23 {.field_id = "d",.field_init = ima_eventdigest_init,
24 .field_show = ima_show_template_digest},
25 {.field_id = "n",.field_init = ima_eventname_init,
26 .field_show = ima_show_template_string},
21}; 27};
22 28
23static struct ima_template_field *ima_lookup_template_field( 29static struct ima_template_field *lookup_template_field(const char *field_id)
24 const char *field_id)
25{ 30{
26 int i; 31 int i;
27 32
@@ -32,7 +37,7 @@ static struct ima_template_field *ima_lookup_template_field(
32 return NULL; 37 return NULL;
33} 38}
34 39
35static int ima_template_fmt_size(char *template_fmt) 40static int template_fmt_size(char *template_fmt)
36{ 41{
37 char c; 42 char c;
38 int template_fmt_len = strlen(template_fmt); 43 int template_fmt_len = strlen(template_fmt);
@@ -53,7 +58,7 @@ static int template_desc_init_fields(char *template_fmt,
53 int *num_fields) 58 int *num_fields)
54{ 59{
55 char *c, *template_fmt_ptr = template_fmt; 60 char *c, *template_fmt_ptr = template_fmt;
56 int template_num_fields = ima_template_fmt_size(template_fmt); 61 int template_num_fields = template_fmt_size(template_fmt);
57 int i, result = 0; 62 int i, result = 0;
58 63
59 if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX) 64 if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX)
@@ -66,7 +71,7 @@ static int template_desc_init_fields(char *template_fmt,
66 } 71 }
67 for (i = 0; (c = strsep(&template_fmt_ptr, "|")) != NULL && 72 for (i = 0; (c = strsep(&template_fmt_ptr, "|")) != NULL &&
68 i < template_num_fields; i++) { 73 i < template_num_fields; i++) {
69 struct ima_template_field *f = ima_lookup_template_field(c); 74 struct ima_template_field *f = lookup_template_field(c);
70 75
71 if (!f) { 76 if (!f) {
72 result = -ENOENT; 77 result = -ENOENT;
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
new file mode 100644
index 000000000000..e13fc7c04ebc
--- /dev/null
+++ b/security/integrity/ima/ima_template_lib.c
@@ -0,0 +1,193 @@
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 "ima_template_lib.h"
16
17enum data_formats { DATA_FMT_DIGEST = 0, DATA_FMT_EVENT_NAME, DATA_FMT_STRING };
18static int ima_write_template_field_data(const void *data, const u32 datalen,
19 enum data_formats datafmt,
20 struct ima_field_data *field_data)
21{
22 u8 *buf, *buf_ptr;
23 u32 buflen;
24
25 switch (datafmt) {
26 case DATA_FMT_EVENT_NAME:
27 buflen = IMA_EVENT_NAME_LEN_MAX + 1;
28 break;
29 case DATA_FMT_STRING:
30 buflen = datalen + 1;
31 break;
32 default:
33 buflen = datalen;
34 }
35
36 buf = kzalloc(buflen, GFP_KERNEL);
37 if (!buf)
38 return -ENOMEM;
39
40 memcpy(buf, data, datalen);
41
42 /*
43 * Replace all space characters with underscore for event names and
44 * strings. This avoid that, during the parsing of a measurements list,
45 * filenames with spaces or that end with the suffix ' (deleted)' are
46 * split into multiple template fields (the space is the delimitator
47 * character for measurements lists in ASCII format).
48 */
49 if (datafmt == DATA_FMT_EVENT_NAME || datafmt == DATA_FMT_STRING) {
50 for (buf_ptr = buf; buf_ptr - buf < datalen; buf_ptr++)
51 if (*buf_ptr == ' ')
52 *buf_ptr = '_';
53 }
54
55 field_data->data = buf;
56 field_data->len = buflen;
57 return 0;
58}
59
60static void ima_show_template_data_ascii(struct seq_file *m,
61 enum ima_show_type show,
62 enum data_formats datafmt,
63 struct ima_field_data *field_data)
64{
65 switch (datafmt) {
66 case DATA_FMT_DIGEST:
67 ima_print_digest(m, field_data->data, field_data->len);
68 break;
69 case DATA_FMT_STRING:
70 seq_printf(m, "%s", field_data->data);
71 break;
72 default:
73 break;
74 }
75}
76
77static void ima_show_template_data_binary(struct seq_file *m,
78 enum ima_show_type show,
79 enum data_formats datafmt,
80 struct ima_field_data *field_data)
81{
82 ima_putc(m, &field_data->len, sizeof(u32));
83 if (!field_data->len)
84 return;
85 ima_putc(m, field_data->data, field_data->len);
86}
87
88static void ima_show_template_field_data(struct seq_file *m,
89 enum ima_show_type show,
90 enum data_formats datafmt,
91 struct ima_field_data *field_data)
92{
93 switch (show) {
94 case IMA_SHOW_ASCII:
95 ima_show_template_data_ascii(m, show, datafmt, field_data);
96 break;
97 case IMA_SHOW_BINARY:
98 ima_show_template_data_binary(m, show, datafmt, field_data);
99 break;
100 default:
101 break;
102 }
103}
104
105void ima_show_template_digest(struct seq_file *m, enum ima_show_type show,
106 struct ima_field_data *field_data)
107{
108 ima_show_template_field_data(m, show, DATA_FMT_DIGEST, field_data);
109}
110
111void ima_show_template_string(struct seq_file *m, enum ima_show_type show,
112 struct ima_field_data *field_data)
113{
114 ima_show_template_field_data(m, show, DATA_FMT_STRING, field_data);
115}
116
117/*
118 * This function writes the digest of an event.
119 */
120int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
121 const unsigned char *filename,
122 struct ima_field_data *field_data)
123{
124 struct {
125 struct ima_digest_data hdr;
126 char digest[IMA_MAX_DIGEST_SIZE];
127 } hash;
128 u8 *cur_digest = hash.hdr.digest;
129 u32 cur_digestsize = IMA_DIGEST_SIZE;
130 struct inode *inode;
131 int result;
132
133 memset(&hash, 0, sizeof(hash));
134
135 if (!iint) /* recording a violation. */
136 goto out;
137
138 if (iint->ima_hash->algo == ima_hash_algo) {
139 cur_digest = iint->ima_hash->digest;
140 cur_digestsize = iint->ima_hash->length;
141 goto out;
142 }
143
144 if (!file) /* missing info to re-calculate the digest */
145 return -EINVAL;
146
147 inode = file_inode(file);
148 hash.hdr.algo = ima_hash_algo;
149 result = ima_calc_file_hash(file, &hash.hdr);
150 if (result) {
151 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
152 filename, "collect_data",
153 "failed", result, 0);
154 return result;
155 }
156out:
157 return ima_write_template_field_data(cur_digest, cur_digestsize,
158 DATA_FMT_DIGEST, field_data);
159}
160
161/*
162 * This function writes the name of an event.
163 */
164int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file,
165 const unsigned char *filename,
166 struct ima_field_data *field_data)
167{
168 const char *cur_filename = NULL;
169 u32 cur_filename_len = 0;
170
171 BUG_ON(filename == NULL && file == NULL);
172
173 if (filename) {
174 cur_filename = filename;
175 cur_filename_len = strlen(filename);
176
177 if (cur_filename_len <= IMA_EVENT_NAME_LEN_MAX)
178 goto out;
179 }
180
181 if (file) {
182 cur_filename = file->f_dentry->d_name.name;
183 cur_filename_len = strlen(cur_filename);
184 } else
185 /*
186 * Truncate filename if the latter is too long and
187 * the file descriptor is not available.
188 */
189 cur_filename_len = IMA_EVENT_NAME_LEN_MAX;
190out:
191 return ima_write_template_field_data(cur_filename, cur_filename_len,
192 DATA_FMT_EVENT_NAME, field_data);
193}
diff --git a/security/integrity/ima/ima_template_lib.h b/security/integrity/ima/ima_template_lib.h
new file mode 100644
index 000000000000..2cecc83a928d
--- /dev/null
+++ b/security/integrity/ima/ima_template_lib.h
@@ -0,0 +1,31 @@
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_string(struct seq_file *m, enum ima_show_type show,
24 struct ima_field_data *field_data);
25int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
26 const unsigned char *filename,
27 struct ima_field_data *field_data);
28int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file,
29 const unsigned char *filename,
30 struct ima_field_data *field_data);
31#endif /* __LINUX_IMA_TEMPLATE_LIB_H */