hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/security/integrity/ima/ima_template.c
....@@ -1,19 +1,13 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2013 Politecnico di Torino, Italy
3
- * TORSEC group -- http://security.polito.it
4
+ * TORSEC group -- https://security.polito.it
45 *
56 * 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.
117 *
128 * File: ima_template.c
139 * Helpers to manage template descriptors.
1410 */
15
-
16
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1711
1812 #include <linux/rculist.h>
1913 #include "ima.h"
....@@ -26,6 +20,8 @@
2620 {.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT},
2721 {.name = "ima-ng", .fmt = "d-ng|n-ng"},
2822 {.name = "ima-sig", .fmt = "d-ng|n-ng|sig"},
23
+ {.name = "ima-buf", .fmt = "d-ng|n-ng|buf"},
24
+ {.name = "ima-modsig", .fmt = "d-ng|n-ng|sig|d-modsig|modsig"},
2925 {.name = "", .fmt = ""}, /* placeholder for a custom format */
3026 };
3127
....@@ -33,7 +29,7 @@
3329 static DEFINE_SPINLOCK(template_list);
3430 static int template_setup_done;
3531
36
-static struct ima_template_field supported_fields[] = {
32
+static const struct ima_template_field supported_fields[] = {
3733 {.field_id = "d", .field_init = ima_eventdigest_init,
3834 .field_show = ima_show_template_digest},
3935 {.field_id = "n", .field_init = ima_eventname_init,
....@@ -44,14 +40,41 @@
4440 .field_show = ima_show_template_string},
4541 {.field_id = "sig", .field_init = ima_eventsig_init,
4642 .field_show = ima_show_template_sig},
43
+ {.field_id = "buf", .field_init = ima_eventbuf_init,
44
+ .field_show = ima_show_template_buf},
45
+ {.field_id = "d-modsig", .field_init = ima_eventdigest_modsig_init,
46
+ .field_show = ima_show_template_digest_ng},
47
+ {.field_id = "modsig", .field_init = ima_eventmodsig_init,
48
+ .field_show = ima_show_template_sig},
4749 };
48
-#define MAX_TEMPLATE_NAME_LEN 15
50
+
51
+/*
52
+ * Used when restoring measurements carried over from a kexec. 'd' and 'n' don't
53
+ * need to be accounted for since they shouldn't be defined in the same template
54
+ * description as 'd-ng' and 'n-ng' respectively.
55
+ */
56
+#define MAX_TEMPLATE_NAME_LEN sizeof("d-ng|n-ng|sig|buf|d-modisg|modsig")
4957
5058 static struct ima_template_desc *ima_template;
51
-static struct ima_template_desc *lookup_template_desc(const char *name);
52
-static int template_desc_init_fields(const char *template_fmt,
53
- struct ima_template_field ***fields,
54
- int *num_fields);
59
+
60
+/**
61
+ * ima_template_has_modsig - Check whether template has modsig-related fields.
62
+ * @ima_template: IMA template to check.
63
+ *
64
+ * Tells whether the given template has fields referencing a file's appended
65
+ * signature.
66
+ */
67
+bool ima_template_has_modsig(const struct ima_template_desc *ima_template)
68
+{
69
+ int i;
70
+
71
+ for (i = 0; i < ima_template->num_fields; i++)
72
+ if (!strcmp(ima_template->fields[i]->field_id, "modsig") ||
73
+ !strcmp(ima_template->fields[i]->field_id, "d-modsig"))
74
+ return true;
75
+
76
+ return false;
77
+}
5578
5679 static int __init ima_template_setup(char *str)
5780 {
....@@ -112,7 +135,7 @@
112135 }
113136 __setup("ima_template_fmt=", ima_template_fmt_setup);
114137
115
-static struct ima_template_desc *lookup_template_desc(const char *name)
138
+struct ima_template_desc *lookup_template_desc(const char *name)
116139 {
117140 struct ima_template_desc *template_desc;
118141 int found = 0;
....@@ -129,7 +152,8 @@
129152 return found ? template_desc : NULL;
130153 }
131154
132
-static struct ima_template_field *lookup_template_field(const char *field_id)
155
+static const struct ima_template_field *
156
+lookup_template_field(const char *field_id)
133157 {
134158 int i;
135159
....@@ -156,12 +180,12 @@
156180 return j + 1;
157181 }
158182
159
-static int template_desc_init_fields(const char *template_fmt,
160
- struct ima_template_field ***fields,
161
- int *num_fields)
183
+int template_desc_init_fields(const char *template_fmt,
184
+ const struct ima_template_field ***fields,
185
+ int *num_fields)
162186 {
163187 const char *template_fmt_ptr;
164
- struct ima_template_field *found_fields[IMA_TEMPLATE_NUM_FIELDS_MAX];
188
+ const struct ima_template_field *found_fields[IMA_TEMPLATE_NUM_FIELDS_MAX];
165189 int template_num_fields;
166190 int i, len;
167191
....@@ -196,11 +220,11 @@
196220 }
197221
198222 if (fields && num_fields) {
199
- *fields = kmalloc_array(i, sizeof(*fields), GFP_KERNEL);
223
+ *fields = kmalloc_array(i, sizeof(**fields), GFP_KERNEL);
200224 if (*fields == NULL)
201225 return -ENOMEM;
202226
203
- memcpy(*fields, found_fields, i * sizeof(*fields));
227
+ memcpy(*fields, found_fields, i * sizeof(**fields));
204228 *num_fields = i;
205229 }
206230
....@@ -266,8 +290,11 @@
266290
267291 template_desc->name = "";
268292 template_desc->fmt = kstrdup(template_name, GFP_KERNEL);
269
- if (!template_desc->fmt)
293
+ if (!template_desc->fmt) {
294
+ kfree(template_desc);
295
+ template_desc = NULL;
270296 goto out;
297
+ }
271298
272299 spin_lock(&template_list);
273300 list_add_tail_rcu(&template_desc->list, &defined_templates);
....@@ -281,20 +308,30 @@
281308 int template_data_size,
282309 struct ima_template_entry **entry)
283310 {
311
+ struct tpm_digest *digests;
284312 int ret = 0;
285313 int i;
286314
287
- *entry = kzalloc(sizeof(**entry) +
288
- template_desc->num_fields * sizeof(struct ima_field_data),
289
- GFP_NOFS);
315
+ *entry = kzalloc(struct_size(*entry, template_data,
316
+ template_desc->num_fields), GFP_NOFS);
290317 if (!*entry)
291318 return -ENOMEM;
319
+
320
+ digests = kcalloc(NR_BANKS(ima_tpm_chip) + ima_extra_slots,
321
+ sizeof(*digests), GFP_NOFS);
322
+ if (!digests) {
323
+ kfree(*entry);
324
+ return -ENOMEM;
325
+ }
326
+
327
+ (*entry)->digests = digests;
292328
293329 ret = ima_parse_buf(template_data, template_data + template_data_size,
294330 NULL, template_desc->num_fields,
295331 (*entry)->template_data, NULL, NULL,
296332 ENFORCE_FIELDS | ENFORCE_BUFEND, "template data");
297333 if (ret < 0) {
334
+ kfree((*entry)->digests);
298335 kfree(*entry);
299336 return ret;
300337 }
....@@ -327,6 +364,7 @@
327364 int ima_restore_measurement_list(loff_t size, void *buf)
328365 {
329366 char template_name[MAX_TEMPLATE_NAME_LEN];
367
+ unsigned char zero[TPM_DIGEST_SIZE] = { 0 };
330368
331369 struct ima_kexec_hdr *khdr = buf;
332370 struct ima_field_data hdr[HDR__LAST] = {
....@@ -426,10 +464,19 @@
426464 if (ret < 0)
427465 break;
428466
429
- memcpy(entry->digest, hdr[HDR_DIGEST].data,
430
- hdr[HDR_DIGEST].len);
431
- entry->pcr = !ima_canonical_fmt ? *(hdr[HDR_PCR].data) :
432
- le32_to_cpu(*(hdr[HDR_PCR].data));
467
+ if (memcmp(hdr[HDR_DIGEST].data, zero, sizeof(zero))) {
468
+ ret = ima_calc_field_array_hash(
469
+ &entry->template_data[0],
470
+ entry);
471
+ if (ret < 0) {
472
+ pr_err("cannot calculate template digest\n");
473
+ ret = -EINVAL;
474
+ break;
475
+ }
476
+ }
477
+
478
+ entry->pcr = !ima_canonical_fmt ? *(u32 *)(hdr[HDR_PCR].data) :
479
+ le32_to_cpu(*(u32 *)(hdr[HDR_PCR].data));
433480 ret = ima_restore_measurement_entry(entry);
434481 if (ret < 0)
435482 break;