ima_template.c (8c57a5e7b2820f349c95b8c8393fec1e0f4070d2) ima_template.c (94c3aac567a9ddb9e868a7fae3c927c08b51b7c6)
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

--- 23 unchanged lines hidden (view full) ---

32 .field_show = ima_show_template_string},
33 {.field_id = "d-ng", .field_init = ima_eventdigest_ng_init,
34 .field_show = ima_show_template_digest_ng},
35 {.field_id = "n-ng", .field_init = ima_eventname_ng_init,
36 .field_show = ima_show_template_string},
37 {.field_id = "sig", .field_init = ima_eventsig_init,
38 .field_show = ima_show_template_sig},
39};
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

--- 23 unchanged lines hidden (view full) ---

32 .field_show = ima_show_template_string},
33 {.field_id = "d-ng", .field_init = ima_eventdigest_ng_init,
34 .field_show = ima_show_template_digest_ng},
35 {.field_id = "n-ng", .field_init = ima_eventname_ng_init,
36 .field_show = ima_show_template_string},
37 {.field_id = "sig", .field_init = ima_eventsig_init,
38 .field_show = ima_show_template_sig},
39};
40#define MAX_TEMPLATE_NAME_LEN 15
40
41static struct ima_template_desc *ima_template;
42static struct ima_template_desc *lookup_template_desc(const char *name);
43static int template_desc_init_fields(const char *template_fmt,
44 struct ima_template_field ***fields,
45 int *num_fields);
46
47static int __init ima_template_setup(char *str)

--- 152 unchanged lines hidden (view full) ---

200 &(template->num_fields));
201 if (result < 0)
202 pr_err("template %s init failed, result: %d\n",
203 (strlen(template->name) ?
204 template->name : template->fmt), result);
205
206 return result;
207}
41
42static struct ima_template_desc *ima_template;
43static struct ima_template_desc *lookup_template_desc(const char *name);
44static int template_desc_init_fields(const char *template_fmt,
45 struct ima_template_field ***fields,
46 int *num_fields);
47
48static int __init ima_template_setup(char *str)

--- 152 unchanged lines hidden (view full) ---

201 &(template->num_fields));
202 if (result < 0)
203 pr_err("template %s init failed, result: %d\n",
204 (strlen(template->name) ?
205 template->name : template->fmt), result);
206
207 return result;
208}
209
210static int ima_restore_template_data(struct ima_template_desc *template_desc,
211 void *template_data,
212 int template_data_size,
213 struct ima_template_entry **entry)
214{
215 struct binary_field_data {
216 u32 len;
217 u8 data[0];
218 } __packed;
219
220 struct binary_field_data *field_data;
221 int offset = 0;
222 int ret = 0;
223 int i;
224
225 *entry = kzalloc(sizeof(**entry) +
226 template_desc->num_fields * sizeof(struct ima_field_data),
227 GFP_NOFS);
228 if (!*entry)
229 return -ENOMEM;
230
231 (*entry)->template_desc = template_desc;
232 for (i = 0; i < template_desc->num_fields; i++) {
233 field_data = template_data + offset;
234
235 /* Each field of the template data is prefixed with a length. */
236 if (offset > (template_data_size - sizeof(*field_data))) {
237 pr_err("Restoring the template field failed\n");
238 ret = -EINVAL;
239 break;
240 }
241 offset += sizeof(*field_data);
242
243 if (offset > (template_data_size - field_data->len)) {
244 pr_err("Restoring the template field data failed\n");
245 ret = -EINVAL;
246 break;
247 }
248 offset += field_data->len;
249
250 (*entry)->template_data[i].len = field_data->len;
251 (*entry)->template_data_len += sizeof(field_data->len);
252
253 (*entry)->template_data[i].data =
254 kzalloc(field_data->len + 1, GFP_KERNEL);
255 if (!(*entry)->template_data[i].data) {
256 ret = -ENOMEM;
257 break;
258 }
259 memcpy((*entry)->template_data[i].data, field_data->data,
260 field_data->len);
261 (*entry)->template_data_len += field_data->len;
262 }
263
264 if (ret < 0) {
265 ima_free_template_entry(*entry);
266 *entry = NULL;
267 }
268
269 return ret;
270}
271
272/* Restore the serialized binary measurement list without extending PCRs. */
273int ima_restore_measurement_list(loff_t size, void *buf)
274{
275 struct binary_hdr_v1 {
276 u32 pcr;
277 u8 digest[TPM_DIGEST_SIZE];
278 u32 template_name_len;
279 char template_name[0];
280 } __packed;
281 char template_name[MAX_TEMPLATE_NAME_LEN];
282
283 struct binary_data_v1 {
284 u32 template_data_size;
285 char template_data[0];
286 } __packed;
287
288 struct ima_kexec_hdr *khdr = buf;
289 struct binary_hdr_v1 *hdr_v1;
290 struct binary_data_v1 *data_v1;
291
292 void *bufp = buf + sizeof(*khdr);
293 void *bufendp = buf + khdr->buffer_size;
294 struct ima_template_entry *entry;
295 struct ima_template_desc *template_desc;
296 unsigned long count = 0;
297 int ret = 0;
298
299 if (!buf || size < sizeof(*khdr))
300 return 0;
301
302 if (khdr->version != 1) {
303 pr_err("attempting to restore a incompatible measurement list");
304 return -EINVAL;
305 }
306
307 if (khdr->count > ULONG_MAX - 1) {
308 pr_err("attempting to restore too many measurements");
309 return -EINVAL;
310 }
311
312 /*
313 * ima kexec buffer prefix: version, buffer size, count
314 * v1 format: pcr, digest, template-name-len, template-name,
315 * template-data-size, template-data
316 */
317 while ((bufp < bufendp) && (count++ < khdr->count)) {
318 hdr_v1 = bufp;
319 if (bufp > (bufendp - sizeof(*hdr_v1))) {
320 pr_err("attempting to restore partial measurement\n");
321 ret = -EINVAL;
322 break;
323 }
324 bufp += sizeof(*hdr_v1);
325
326 if ((hdr_v1->template_name_len >= MAX_TEMPLATE_NAME_LEN) ||
327 (bufp > (bufendp - hdr_v1->template_name_len))) {
328 pr_err("attempting to restore a template name \
329 that is too long\n");
330 ret = -EINVAL;
331 break;
332 }
333 data_v1 = bufp += (u_int8_t)hdr_v1->template_name_len;
334
335 /* template name is not null terminated */
336 memcpy(template_name, hdr_v1->template_name,
337 hdr_v1->template_name_len);
338 template_name[hdr_v1->template_name_len] = 0;
339
340 if (strcmp(template_name, "ima") == 0) {
341 pr_err("attempting to restore an unsupported \
342 template \"%s\" failed\n", template_name);
343 ret = -EINVAL;
344 break;
345 }
346
347 /* get template format */
348 template_desc = lookup_template_desc(template_name);
349 if (!template_desc) {
350 pr_err("template \"%s\" not found\n", template_name);
351 ret = -EINVAL;
352 break;
353 }
354
355 if (bufp > (bufendp - sizeof(data_v1->template_data_size))) {
356 pr_err("restoring the template data size failed\n");
357 ret = -EINVAL;
358 break;
359 }
360 bufp += (u_int8_t) sizeof(data_v1->template_data_size);
361
362 if (bufp > (bufendp - data_v1->template_data_size)) {
363 pr_err("restoring the template data failed\n");
364 ret = -EINVAL;
365 break;
366 }
367 bufp += data_v1->template_data_size;
368
369 ret = ima_restore_template_data(template_desc,
370 data_v1->template_data,
371 data_v1->template_data_size,
372 &entry);
373 if (ret < 0)
374 break;
375
376 memcpy(entry->digest, hdr_v1->digest, TPM_DIGEST_SIZE);
377 entry->pcr = hdr_v1->pcr;
378 ret = ima_restore_measurement_entry(entry);
379 if (ret < 0)
380 break;
381
382 }
383 return ret;
384}