1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17
18#include <linux/rculist.h>
19#include "ima.h"
20#include "ima_template_lib.h"
21
22enum header_fields { HDR_PCR, HDR_DIGEST, HDR_TEMPLATE_NAME,
23 HDR_TEMPLATE_DATA, HDR__LAST };
24
25static struct ima_template_desc builtin_templates[] = {
26 {.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT},
27 {.name = "ima-ng", .fmt = "d-ng|n-ng"},
28 {.name = "ima-sig", .fmt = "d-ng|n-ng|sig"},
29 {.name = "ima-buf", .fmt = "d-ng|n-ng|buf"},
30 {.name = "ima-modsig", .fmt = "d-ng|n-ng|sig|d-modsig|modsig"},
31 {.name = "", .fmt = ""},
32};
33
34static LIST_HEAD(defined_templates);
35static DEFINE_SPINLOCK(template_list);
36
37static const struct ima_template_field supported_fields[] = {
38 {.field_id = "d", .field_init = ima_eventdigest_init,
39 .field_show = ima_show_template_digest},
40 {.field_id = "n", .field_init = ima_eventname_init,
41 .field_show = ima_show_template_string},
42 {.field_id = "d-ng", .field_init = ima_eventdigest_ng_init,
43 .field_show = ima_show_template_digest_ng},
44 {.field_id = "n-ng", .field_init = ima_eventname_ng_init,
45 .field_show = ima_show_template_string},
46 {.field_id = "sig", .field_init = ima_eventsig_init,
47 .field_show = ima_show_template_sig},
48 {.field_id = "buf", .field_init = ima_eventbuf_init,
49 .field_show = ima_show_template_buf},
50 {.field_id = "d-modsig", .field_init = ima_eventdigest_modsig_init,
51 .field_show = ima_show_template_digest_ng},
52 {.field_id = "modsig", .field_init = ima_eventmodsig_init,
53 .field_show = ima_show_template_sig},
54};
55
56
57
58
59
60
61#define MAX_TEMPLATE_NAME_LEN sizeof("d-ng|n-ng|sig|buf|d-modisg|modsig")
62
63static struct ima_template_desc *ima_template;
64
65
66
67
68
69
70
71
72bool ima_template_has_modsig(const struct ima_template_desc *ima_template)
73{
74 int i;
75
76 for (i = 0; i < ima_template->num_fields; i++)
77 if (!strcmp(ima_template->fields[i]->field_id, "modsig") ||
78 !strcmp(ima_template->fields[i]->field_id, "d-modsig"))
79 return true;
80
81 return false;
82}
83
84static int __init ima_template_setup(char *str)
85{
86 struct ima_template_desc *template_desc;
87 int template_len = strlen(str);
88
89 if (ima_template)
90 return 1;
91
92 ima_init_template_list();
93
94
95
96
97
98 template_desc = lookup_template_desc(str);
99 if (!template_desc) {
100 pr_err("template %s not found, using %s\n",
101 str, CONFIG_IMA_DEFAULT_TEMPLATE);
102 return 1;
103 }
104
105
106
107
108
109 if (template_len == 3 && strcmp(str, IMA_TEMPLATE_IMA_NAME) == 0 &&
110 ima_hash_algo != HASH_ALGO_SHA1 && ima_hash_algo != HASH_ALGO_MD5) {
111 pr_err("template does not support hash alg\n");
112 return 1;
113 }
114
115 ima_template = template_desc;
116 return 1;
117}
118__setup("ima_template=", ima_template_setup);
119
120static int __init ima_template_fmt_setup(char *str)
121{
122 int num_templates = ARRAY_SIZE(builtin_templates);
123
124 if (ima_template)
125 return 1;
126
127 if (template_desc_init_fields(str, NULL, NULL) < 0) {
128 pr_err("format string '%s' not valid, using template %s\n",
129 str, CONFIG_IMA_DEFAULT_TEMPLATE);
130 return 1;
131 }
132
133 builtin_templates[num_templates - 1].fmt = str;
134 ima_template = builtin_templates + num_templates - 1;
135
136 return 1;
137}
138__setup("ima_template_fmt=", ima_template_fmt_setup);
139
140struct ima_template_desc *lookup_template_desc(const char *name)
141{
142 struct ima_template_desc *template_desc;
143 int found = 0;
144
145 rcu_read_lock();
146 list_for_each_entry_rcu(template_desc, &defined_templates, list) {
147 if ((strcmp(template_desc->name, name) == 0) ||
148 (strcmp(template_desc->fmt, name) == 0)) {
149 found = 1;
150 break;
151 }
152 }
153 rcu_read_unlock();
154 return found ? template_desc : NULL;
155}
156
157static const struct ima_template_field *
158lookup_template_field(const char *field_id)
159{
160 int i;
161
162 for (i = 0; i < ARRAY_SIZE(supported_fields); i++)
163 if (strncmp(supported_fields[i].field_id, field_id,
164 IMA_TEMPLATE_FIELD_ID_MAX_LEN) == 0)
165 return &supported_fields[i];
166 return NULL;
167}
168
169static int template_fmt_size(const char *template_fmt)
170{
171 char c;
172 int template_fmt_len = strlen(template_fmt);
173 int i = 0, j = 0;
174
175 while (i < template_fmt_len) {
176 c = template_fmt[i];
177 if (c == '|')
178 j++;
179 i++;
180 }
181
182 return j + 1;
183}
184
185int template_desc_init_fields(const char *template_fmt,
186 const struct ima_template_field ***fields,
187 int *num_fields)
188{
189 const char *template_fmt_ptr;
190 const struct ima_template_field *found_fields[IMA_TEMPLATE_NUM_FIELDS_MAX];
191 int template_num_fields;
192 int i, len;
193
194 if (num_fields && *num_fields > 0)
195 return 0;
196
197 template_num_fields = template_fmt_size(template_fmt);
198
199 if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX) {
200 pr_err("format string '%s' contains too many fields\n",
201 template_fmt);
202 return -EINVAL;
203 }
204
205 for (i = 0, template_fmt_ptr = template_fmt; i < template_num_fields;
206 i++, template_fmt_ptr += len + 1) {
207 char tmp_field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN + 1];
208
209 len = strchrnul(template_fmt_ptr, '|') - template_fmt_ptr;
210 if (len == 0 || len > IMA_TEMPLATE_FIELD_ID_MAX_LEN) {
211 pr_err("Invalid field with length %d\n", len);
212 return -EINVAL;
213 }
214
215 memcpy(tmp_field_id, template_fmt_ptr, len);
216 tmp_field_id[len] = '\0';
217 found_fields[i] = lookup_template_field(tmp_field_id);
218 if (!found_fields[i]) {
219 pr_err("field '%s' not found\n", tmp_field_id);
220 return -ENOENT;
221 }
222 }
223
224 if (fields && num_fields) {
225 *fields = kmalloc_array(i, sizeof(*fields), GFP_KERNEL);
226 if (*fields == NULL)
227 return -ENOMEM;
228
229 memcpy(*fields, found_fields, i * sizeof(*fields));
230 *num_fields = i;
231 }
232
233 return 0;
234}
235
236void ima_init_template_list(void)
237{
238 int i;
239
240 if (!list_empty(&defined_templates))
241 return;
242
243 spin_lock(&template_list);
244 for (i = 0; i < ARRAY_SIZE(builtin_templates); i++) {
245 list_add_tail_rcu(&builtin_templates[i].list,
246 &defined_templates);
247 }
248 spin_unlock(&template_list);
249}
250
251struct ima_template_desc *ima_template_desc_current(void)
252{
253 if (!ima_template) {
254 ima_init_template_list();
255 ima_template =
256 lookup_template_desc(CONFIG_IMA_DEFAULT_TEMPLATE);
257 }
258 return ima_template;
259}
260
261int __init ima_init_template(void)
262{
263 struct ima_template_desc *template = ima_template_desc_current();
264 int result;
265
266 result = template_desc_init_fields(template->fmt,
267 &(template->fields),
268 &(template->num_fields));
269 if (result < 0)
270 pr_err("template %s init failed, result: %d\n",
271 (strlen(template->name) ?
272 template->name : template->fmt), result);
273
274 return result;
275}
276
277static struct ima_template_desc *restore_template_fmt(char *template_name)
278{
279 struct ima_template_desc *template_desc = NULL;
280 int ret;
281
282 ret = template_desc_init_fields(template_name, NULL, NULL);
283 if (ret < 0) {
284 pr_err("attempting to initialize the template \"%s\" failed\n",
285 template_name);
286 goto out;
287 }
288
289 template_desc = kzalloc(sizeof(*template_desc), GFP_KERNEL);
290 if (!template_desc)
291 goto out;
292
293 template_desc->name = "";
294 template_desc->fmt = kstrdup(template_name, GFP_KERNEL);
295 if (!template_desc->fmt)
296 goto out;
297
298 spin_lock(&template_list);
299 list_add_tail_rcu(&template_desc->list, &defined_templates);
300 spin_unlock(&template_list);
301out:
302 return template_desc;
303}
304
305static int ima_restore_template_data(struct ima_template_desc *template_desc,
306 void *template_data,
307 int template_data_size,
308 struct ima_template_entry **entry)
309{
310 int ret = 0;
311 int i;
312
313 *entry = kzalloc(struct_size(*entry, template_data,
314 template_desc->num_fields), GFP_NOFS);
315 if (!*entry)
316 return -ENOMEM;
317
318 ret = ima_parse_buf(template_data, template_data + template_data_size,
319 NULL, template_desc->num_fields,
320 (*entry)->template_data, NULL, NULL,
321 ENFORCE_FIELDS | ENFORCE_BUFEND, "template data");
322 if (ret < 0) {
323 kfree(*entry);
324 return ret;
325 }
326
327 (*entry)->template_desc = template_desc;
328 for (i = 0; i < template_desc->num_fields; i++) {
329 struct ima_field_data *field_data = &(*entry)->template_data[i];
330 u8 *data = field_data->data;
331
332 (*entry)->template_data[i].data =
333 kzalloc(field_data->len + 1, GFP_KERNEL);
334 if (!(*entry)->template_data[i].data) {
335 ret = -ENOMEM;
336 break;
337 }
338 memcpy((*entry)->template_data[i].data, data, field_data->len);
339 (*entry)->template_data_len += sizeof(field_data->len);
340 (*entry)->template_data_len += field_data->len;
341 }
342
343 if (ret < 0) {
344 ima_free_template_entry(*entry);
345 *entry = NULL;
346 }
347
348 return ret;
349}
350
351
352int ima_restore_measurement_list(loff_t size, void *buf)
353{
354 char template_name[MAX_TEMPLATE_NAME_LEN];
355
356 struct ima_kexec_hdr *khdr = buf;
357 struct ima_field_data hdr[HDR__LAST] = {
358 [HDR_PCR] = {.len = sizeof(u32)},
359 [HDR_DIGEST] = {.len = TPM_DIGEST_SIZE},
360 };
361
362 void *bufp = buf + sizeof(*khdr);
363 void *bufendp;
364 struct ima_template_entry *entry;
365 struct ima_template_desc *template_desc;
366 DECLARE_BITMAP(hdr_mask, HDR__LAST);
367 unsigned long count = 0;
368 int ret = 0;
369
370 if (!buf || size < sizeof(*khdr))
371 return 0;
372
373 if (ima_canonical_fmt) {
374 khdr->version = le16_to_cpu(khdr->version);
375 khdr->count = le64_to_cpu(khdr->count);
376 khdr->buffer_size = le64_to_cpu(khdr->buffer_size);
377 }
378
379 if (khdr->version != 1) {
380 pr_err("attempting to restore a incompatible measurement list");
381 return -EINVAL;
382 }
383
384 if (khdr->count > ULONG_MAX - 1) {
385 pr_err("attempting to restore too many measurements");
386 return -EINVAL;
387 }
388
389 bitmap_zero(hdr_mask, HDR__LAST);
390 bitmap_set(hdr_mask, HDR_PCR, 1);
391 bitmap_set(hdr_mask, HDR_DIGEST, 1);
392
393
394
395
396
397
398 bufendp = buf + khdr->buffer_size;
399 while ((bufp < bufendp) && (count++ < khdr->count)) {
400 int enforce_mask = ENFORCE_FIELDS;
401
402 enforce_mask |= (count == khdr->count) ? ENFORCE_BUFEND : 0;
403 ret = ima_parse_buf(bufp, bufendp, &bufp, HDR__LAST, hdr, NULL,
404 hdr_mask, enforce_mask, "entry header");
405 if (ret < 0)
406 break;
407
408 if (hdr[HDR_TEMPLATE_NAME].len >= MAX_TEMPLATE_NAME_LEN) {
409 pr_err("attempting to restore a template name that is too long\n");
410 ret = -EINVAL;
411 break;
412 }
413
414
415 memcpy(template_name, hdr[HDR_TEMPLATE_NAME].data,
416 hdr[HDR_TEMPLATE_NAME].len);
417 template_name[hdr[HDR_TEMPLATE_NAME].len] = 0;
418
419 if (strcmp(template_name, "ima") == 0) {
420 pr_err("attempting to restore an unsupported template \"%s\" failed\n",
421 template_name);
422 ret = -EINVAL;
423 break;
424 }
425
426 template_desc = lookup_template_desc(template_name);
427 if (!template_desc) {
428 template_desc = restore_template_fmt(template_name);
429 if (!template_desc)
430 break;
431 }
432
433
434
435
436
437 ret = template_desc_init_fields(template_desc->fmt,
438 &(template_desc->fields),
439 &(template_desc->num_fields));
440 if (ret < 0) {
441 pr_err("attempting to restore the template fmt \"%s\" failed\n",
442 template_desc->fmt);
443 ret = -EINVAL;
444 break;
445 }
446
447 ret = ima_restore_template_data(template_desc,
448 hdr[HDR_TEMPLATE_DATA].data,
449 hdr[HDR_TEMPLATE_DATA].len,
450 &entry);
451 if (ret < 0)
452 break;
453
454 memcpy(entry->digest, hdr[HDR_DIGEST].data,
455 hdr[HDR_DIGEST].len);
456 entry->pcr = !ima_canonical_fmt ? *(hdr[HDR_PCR].data) :
457 le32_to_cpu(*(hdr[HDR_PCR].data));
458 ret = ima_restore_measurement_entry(entry);
459 if (ret < 0)
460 break;
461
462 }
463 return ret;
464}
465