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} |
|