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