1 /* 2 * EIF (Enclave Image Format) related helpers 3 * 4 * Copyright (c) 2024 Dorjoy Chowdhury <dorjoychy111@gmail.com> 5 * 6 * This work is licensed under the terms of the GNU GPL, version 2 or 7 * (at your option) any later version. See the COPYING file in the 8 * top-level directory. 9 */ 10 11 #include "qemu/osdep.h" 12 #include "qemu/bswap.h" 13 #include "qapi/error.h" 14 #include "crypto/hash.h" 15 #include "crypto/x509-utils.h" 16 #include <zlib.h> /* for crc32 */ 17 #include <cbor.h> 18 19 #include "hw/core/eif.h" 20 21 #define MAX_SECTIONS 32 22 23 /* members are ordered according to field order in .eif file */ 24 typedef struct EifHeader { 25 uint8_t magic[4]; /* must be .eif in ascii i.e., [46, 101, 105, 102] */ 26 uint16_t version; 27 uint16_t flags; 28 uint64_t default_memory; 29 uint64_t default_cpus; 30 uint16_t reserved; 31 uint16_t section_cnt; 32 uint64_t section_offsets[MAX_SECTIONS]; 33 uint64_t section_sizes[MAX_SECTIONS]; 34 uint32_t unused; 35 uint32_t eif_crc32; 36 } QEMU_PACKED EifHeader; 37 38 /* members are ordered according to field order in .eif file */ 39 typedef struct EifSectionHeader { 40 /* 41 * 0 = invalid, 1 = kernel, 2 = cmdline, 3 = ramdisk, 4 = signature, 42 * 5 = metadata 43 */ 44 uint16_t section_type; 45 uint16_t flags; 46 uint64_t section_size; 47 } QEMU_PACKED EifSectionHeader; 48 49 enum EifSectionTypes { 50 EIF_SECTION_INVALID = 0, 51 EIF_SECTION_KERNEL = 1, 52 EIF_SECTION_CMDLINE = 2, 53 EIF_SECTION_RAMDISK = 3, 54 EIF_SECTION_SIGNATURE = 4, 55 EIF_SECTION_METADATA = 5, 56 EIF_SECTION_MAX = 6, 57 }; 58 59 static const char *section_type_to_string(uint16_t type) 60 { 61 const char *str; 62 switch (type) { 63 case EIF_SECTION_INVALID: 64 str = "invalid"; 65 break; 66 case EIF_SECTION_KERNEL: 67 str = "kernel"; 68 break; 69 case EIF_SECTION_CMDLINE: 70 str = "cmdline"; 71 break; 72 case EIF_SECTION_RAMDISK: 73 str = "ramdisk"; 74 break; 75 case EIF_SECTION_SIGNATURE: 76 str = "signature"; 77 break; 78 case EIF_SECTION_METADATA: 79 str = "metadata"; 80 break; 81 default: 82 str = "unknown"; 83 break; 84 } 85 86 return str; 87 } 88 89 static bool read_eif_header(FILE *f, EifHeader *header, uint32_t *crc, 90 Error **errp) 91 { 92 size_t got; 93 size_t header_size = sizeof(*header); 94 95 got = fread(header, 1, header_size, f); 96 if (got != header_size) { 97 error_setg(errp, "Failed to read EIF header"); 98 return false; 99 } 100 101 if (memcmp(header->magic, ".eif", 4) != 0) { 102 error_setg(errp, "Invalid EIF image. Magic mismatch."); 103 return false; 104 } 105 106 /* Exclude header->eif_crc32 field from CRC calculation */ 107 *crc = crc32(*crc, (uint8_t *)header, header_size - 4); 108 109 header->version = be16_to_cpu(header->version); 110 header->flags = be16_to_cpu(header->flags); 111 header->default_memory = be64_to_cpu(header->default_memory); 112 header->default_cpus = be64_to_cpu(header->default_cpus); 113 header->reserved = be16_to_cpu(header->reserved); 114 header->section_cnt = be16_to_cpu(header->section_cnt); 115 116 for (int i = 0; i < MAX_SECTIONS; ++i) { 117 header->section_offsets[i] = be64_to_cpu(header->section_offsets[i]); 118 } 119 120 for (int i = 0; i < MAX_SECTIONS; ++i) { 121 header->section_sizes[i] = be64_to_cpu(header->section_sizes[i]); 122 if (header->section_sizes[i] > SSIZE_MAX) { 123 error_setg(errp, "Invalid EIF image. Section size out of bounds"); 124 return false; 125 } 126 } 127 128 header->unused = be32_to_cpu(header->unused); 129 header->eif_crc32 = be32_to_cpu(header->eif_crc32); 130 return true; 131 } 132 133 static bool read_eif_section_header(FILE *f, EifSectionHeader *section_header, 134 uint32_t *crc, Error **errp) 135 { 136 size_t got; 137 size_t section_header_size = sizeof(*section_header); 138 139 got = fread(section_header, 1, section_header_size, f); 140 if (got != section_header_size) { 141 error_setg(errp, "Failed to read EIF section header"); 142 return false; 143 } 144 145 *crc = crc32(*crc, (uint8_t *)section_header, section_header_size); 146 147 section_header->section_type = be16_to_cpu(section_header->section_type); 148 section_header->flags = be16_to_cpu(section_header->flags); 149 section_header->section_size = be64_to_cpu(section_header->section_size); 150 return true; 151 } 152 153 /* 154 * Upon success, the caller is responsible for unlinking and freeing *tmp_path. 155 */ 156 static bool get_tmp_file(const char *template, char **tmp_path, Error **errp) 157 { 158 int tmp_fd; 159 160 *tmp_path = NULL; 161 tmp_fd = g_file_open_tmp(template, tmp_path, NULL); 162 if (tmp_fd < 0 || *tmp_path == NULL) { 163 error_setg(errp, "Failed to create temporary file for template %s", 164 template); 165 return false; 166 } 167 168 close(tmp_fd); 169 return true; 170 } 171 172 static void safe_fclose(FILE *f) 173 { 174 if (f) { 175 fclose(f); 176 } 177 } 178 179 static void safe_unlink(char *f) 180 { 181 if (f) { 182 unlink(f); 183 } 184 } 185 186 /* 187 * Upon success, the caller is reponsible for unlinking and freeing *kernel_path 188 */ 189 static bool read_eif_kernel(FILE *f, uint64_t size, char **kernel_path, 190 uint8_t *kernel, uint32_t *crc, Error **errp) 191 { 192 size_t got; 193 FILE *tmp_file = NULL; 194 195 *kernel_path = NULL; 196 if (!get_tmp_file("eif-kernel-XXXXXX", kernel_path, errp)) { 197 goto cleanup; 198 } 199 200 tmp_file = fopen(*kernel_path, "wb"); 201 if (tmp_file == NULL) { 202 error_setg_errno(errp, errno, "Failed to open temporary file %s", 203 *kernel_path); 204 goto cleanup; 205 } 206 207 got = fread(kernel, 1, size, f); 208 if ((uint64_t) got != size) { 209 error_setg(errp, "Failed to read EIF kernel section data"); 210 goto cleanup; 211 } 212 213 got = fwrite(kernel, 1, size, tmp_file); 214 if ((uint64_t) got != size) { 215 error_setg(errp, "Failed to write EIF kernel section data to temporary" 216 " file"); 217 goto cleanup; 218 } 219 220 *crc = crc32(*crc, kernel, size); 221 fclose(tmp_file); 222 223 return true; 224 225 cleanup: 226 safe_fclose(tmp_file); 227 228 safe_unlink(*kernel_path); 229 g_free(*kernel_path); 230 *kernel_path = NULL; 231 232 return false; 233 } 234 235 static bool read_eif_cmdline(FILE *f, uint64_t size, char *cmdline, 236 uint32_t *crc, Error **errp) 237 { 238 size_t got = fread(cmdline, 1, size, f); 239 if ((uint64_t) got != size) { 240 error_setg(errp, "Failed to read EIF cmdline section data"); 241 return false; 242 } 243 244 *crc = crc32(*crc, (uint8_t *)cmdline, size); 245 return true; 246 } 247 248 static bool read_eif_ramdisk(FILE *eif, FILE *initrd, uint64_t size, 249 uint8_t *ramdisk, uint32_t *crc, Error **errp) 250 { 251 size_t got; 252 253 got = fread(ramdisk, 1, size, eif); 254 if ((uint64_t) got != size) { 255 error_setg(errp, "Failed to read EIF ramdisk section data"); 256 return false; 257 } 258 259 got = fwrite(ramdisk, 1, size, initrd); 260 if ((uint64_t) got != size) { 261 error_setg(errp, "Failed to write EIF ramdisk data to temporary file"); 262 return false; 263 } 264 265 *crc = crc32(*crc, ramdisk, size); 266 return true; 267 } 268 269 static bool get_signature_fingerprint_sha384(FILE *eif, uint64_t size, 270 uint8_t *sha384, 271 uint32_t *crc, 272 Error **errp) 273 { 274 size_t got; 275 g_autofree uint8_t *sig = NULL; 276 g_autofree uint8_t *cert = NULL; 277 cbor_item_t *item = NULL; 278 cbor_item_t *pcr0 = NULL; 279 size_t len; 280 size_t hash_len = QCRYPTO_HASH_DIGEST_LEN_SHA384; 281 struct cbor_pair *pair; 282 struct cbor_load_result result; 283 bool ret = false; 284 285 sig = g_try_malloc(size); 286 if (!sig) { 287 error_setg(errp, "Out of memory reading signature section"); 288 goto cleanup; 289 } 290 291 got = fread(sig, 1, size, eif); 292 if ((uint64_t) got != size) { 293 error_setg(errp, "Failed to read EIF signature section data"); 294 goto cleanup; 295 } 296 297 *crc = crc32(*crc, sig, size); 298 299 item = cbor_load(sig, size, &result); 300 if (!item || result.error.code != CBOR_ERR_NONE) { 301 error_setg(errp, "Failed to load signature section data as CBOR"); 302 goto cleanup; 303 } 304 if (!cbor_isa_array(item) || cbor_array_size(item) < 1) { 305 error_setg(errp, "Invalid signature CBOR"); 306 goto cleanup; 307 } 308 pcr0 = cbor_array_get(item, 0); 309 if (!pcr0) { 310 error_setg(errp, "Failed to get PCR0 signature"); 311 goto cleanup; 312 } 313 if (!cbor_isa_map(pcr0) || cbor_map_size(pcr0) != 2) { 314 error_setg(errp, "Invalid signature CBOR"); 315 goto cleanup; 316 } 317 pair = cbor_map_handle(pcr0); 318 if (!cbor_isa_string(pair->key) || cbor_string_length(pair->key) != 19 || 319 memcmp(cbor_string_handle(pair->key), "signing_certificate", 19) != 0) { 320 error_setg(errp, "Invalid signautre CBOR"); 321 goto cleanup; 322 } 323 if (!cbor_isa_array(pair->value)) { 324 error_setg(errp, "Invalid signature CBOR"); 325 goto cleanup; 326 } 327 len = cbor_array_size(pair->value); 328 if (len == 0) { 329 error_setg(errp, "Invalid signature CBOR"); 330 goto cleanup; 331 } 332 cert = g_try_malloc(len); 333 if (!cert) { 334 error_setg(errp, "Out of memory reading signature section"); 335 goto cleanup; 336 } 337 338 for (int i = 0; i < len; ++i) { 339 cbor_item_t *tmp = cbor_array_get(pair->value, i); 340 if (!tmp) { 341 error_setg(errp, "Invalid signature CBOR"); 342 goto cleanup; 343 } 344 if (!cbor_isa_uint(tmp) || cbor_int_get_width(tmp) != CBOR_INT_8) { 345 cbor_decref(&tmp); 346 error_setg(errp, "Invalid signature CBOR"); 347 goto cleanup; 348 } 349 cert[i] = cbor_get_uint8(tmp); 350 cbor_decref(&tmp); 351 } 352 353 if (qcrypto_get_x509_cert_fingerprint(cert, len, QCRYPTO_HASH_ALGO_SHA384, 354 sha384, &hash_len, errp)) { 355 goto cleanup; 356 } 357 358 ret = true; 359 360 cleanup: 361 if (pcr0) { 362 cbor_decref(&pcr0); 363 } 364 if (item) { 365 cbor_decref(&item); 366 } 367 return ret; 368 } 369 370 /* Expects file to have offset 0 before this function is called */ 371 static long get_file_size(FILE *f, Error **errp) 372 { 373 long size; 374 375 if (fseek(f, 0, SEEK_END) != 0) { 376 error_setg_errno(errp, errno, "Failed to seek to the end of file"); 377 return -1; 378 } 379 380 size = ftell(f); 381 if (size == -1) { 382 error_setg_errno(errp, errno, "Failed to get offset"); 383 return -1; 384 } 385 386 if (fseek(f, 0, SEEK_SET) != 0) { 387 error_setg_errno(errp, errno, "Failed to seek back to the start"); 388 return -1; 389 } 390 391 return size; 392 } 393 394 static bool get_SHA384_digest(GList *list, uint8_t *digest, Error **errp) 395 { 396 size_t digest_len = QCRYPTO_HASH_DIGEST_LEN_SHA384; 397 size_t list_len = g_list_length(list); 398 struct iovec *iovec_list = g_new0(struct iovec, list_len); 399 bool ret = true; 400 GList *l; 401 int i; 402 403 for (i = 0, l = list; l != NULL; l = l->next, i++) { 404 iovec_list[i] = *(struct iovec *) l->data; 405 } 406 407 if (qcrypto_hash_bytesv(QCRYPTO_HASH_ALGO_SHA384, iovec_list, list_len, 408 &digest, &digest_len, errp) < 0) { 409 ret = false; 410 } 411 412 g_free(iovec_list); 413 return ret; 414 } 415 416 static void free_iovec(struct iovec *iov) 417 { 418 if (iov) { 419 g_free(iov->iov_base); 420 g_free(iov); 421 } 422 } 423 424 /* 425 * Upon success, the caller is reponsible for unlinking and freeing 426 * *kernel_path, *initrd_path and freeing *cmdline. 427 */ 428 bool read_eif_file(const char *eif_path, const char *machine_initrd, 429 char **kernel_path, char **initrd_path, char **cmdline, 430 uint8_t *image_sha384, uint8_t *bootstrap_sha384, 431 uint8_t *app_sha384, uint8_t *fingerprint_sha384, 432 bool *signature_found, Error **errp) 433 { 434 FILE *f = NULL; 435 FILE *machine_initrd_f = NULL; 436 FILE *initrd_path_f = NULL; 437 long machine_initrd_size; 438 uint32_t crc = 0; 439 EifHeader eif_header; 440 bool seen_sections[EIF_SECTION_MAX] = {false}; 441 /* kernel + ramdisks + cmdline sha384 hash */ 442 GList *iov_PCR0 = NULL; 443 /* kernel + boot ramdisk + cmdline sha384 hash */ 444 GList *iov_PCR1 = NULL; 445 /* application ramdisk(s) hash */ 446 GList *iov_PCR2 = NULL; 447 uint8_t *ptr = NULL; 448 struct iovec *iov_ptr = NULL; 449 450 *signature_found = false; 451 *kernel_path = *initrd_path = *cmdline = NULL; 452 453 f = fopen(eif_path, "rb"); 454 if (f == NULL) { 455 error_setg_errno(errp, errno, "Failed to open %s", eif_path); 456 goto cleanup; 457 } 458 459 if (!read_eif_header(f, &eif_header, &crc, errp)) { 460 goto cleanup; 461 } 462 463 if (eif_header.version < 4) { 464 error_setg(errp, "Expected EIF version 4 or greater"); 465 goto cleanup; 466 } 467 468 if (eif_header.flags != 0) { 469 error_setg(errp, "Expected EIF flags to be 0"); 470 goto cleanup; 471 } 472 473 if (eif_header.section_cnt > MAX_SECTIONS) { 474 error_setg(errp, "EIF header section count must not be greater than " 475 "%d but found %d", MAX_SECTIONS, eif_header.section_cnt); 476 goto cleanup; 477 } 478 479 for (int i = 0; i < eif_header.section_cnt; ++i) { 480 EifSectionHeader hdr; 481 uint16_t section_type; 482 483 if (eif_header.section_offsets[i] > OFF_MAX) { 484 error_setg(errp, "Invalid EIF image. Section offset out of bounds"); 485 goto cleanup; 486 } 487 if (fseek(f, eif_header.section_offsets[i], SEEK_SET) != 0) { 488 error_setg_errno(errp, errno, "Failed to offset to %" PRIu64 " in EIF file", 489 eif_header.section_offsets[i]); 490 goto cleanup; 491 } 492 493 if (!read_eif_section_header(f, &hdr, &crc, errp)) { 494 goto cleanup; 495 } 496 497 if (hdr.flags != 0) { 498 error_setg(errp, "Expected EIF section header flags to be 0"); 499 goto cleanup; 500 } 501 502 if (eif_header.section_sizes[i] != hdr.section_size) { 503 error_setg(errp, "EIF section size mismatch between header and " 504 "section header: header %" PRIu64 ", section header %" PRIu64, 505 eif_header.section_sizes[i], 506 hdr.section_size); 507 goto cleanup; 508 } 509 510 section_type = hdr.section_type; 511 512 switch (section_type) { 513 case EIF_SECTION_KERNEL: 514 if (seen_sections[EIF_SECTION_KERNEL]) { 515 error_setg(errp, "Invalid EIF image. More than 1 kernel " 516 "section"); 517 goto cleanup; 518 } 519 520 ptr = g_try_malloc(hdr.section_size); 521 if (!ptr) { 522 error_setg(errp, "Out of memory reading kernel section"); 523 goto cleanup; 524 } 525 526 iov_ptr = g_malloc(sizeof(struct iovec)); 527 iov_ptr->iov_base = ptr; 528 iov_ptr->iov_len = hdr.section_size; 529 530 iov_PCR0 = g_list_append(iov_PCR0, iov_ptr); 531 iov_PCR1 = g_list_append(iov_PCR1, iov_ptr); 532 533 if (!read_eif_kernel(f, hdr.section_size, kernel_path, ptr, &crc, 534 errp)) { 535 goto cleanup; 536 } 537 538 break; 539 case EIF_SECTION_CMDLINE: 540 { 541 uint64_t size; 542 uint8_t *cmdline_copy; 543 if (seen_sections[EIF_SECTION_CMDLINE]) { 544 error_setg(errp, "Invalid EIF image. More than 1 cmdline " 545 "section"); 546 goto cleanup; 547 } 548 size = hdr.section_size; 549 *cmdline = g_try_malloc(size + 1); 550 if (!*cmdline) { 551 error_setg(errp, "Out of memory reading command line section"); 552 goto cleanup; 553 } 554 if (!read_eif_cmdline(f, size, *cmdline, &crc, errp)) { 555 goto cleanup; 556 } 557 (*cmdline)[size] = '\0'; 558 559 /* 560 * We make a copy of '*cmdline' for putting it in iovecs so that 561 * we can easily free all the iovec entries later as we cannot 562 * free '*cmdline' which is used by the caller. 563 */ 564 cmdline_copy = g_memdup2(*cmdline, size); 565 566 iov_ptr = g_malloc(sizeof(struct iovec)); 567 iov_ptr->iov_base = cmdline_copy; 568 iov_ptr->iov_len = size; 569 570 iov_PCR0 = g_list_append(iov_PCR0, iov_ptr); 571 iov_PCR1 = g_list_append(iov_PCR1, iov_ptr); 572 break; 573 } 574 case EIF_SECTION_RAMDISK: 575 { 576 if (!seen_sections[EIF_SECTION_RAMDISK]) { 577 /* 578 * If this is the first time we are seeing a ramdisk section, 579 * we need to create the initrd temporary file. 580 */ 581 if (!get_tmp_file("eif-initrd-XXXXXX", initrd_path, errp)) { 582 goto cleanup; 583 } 584 initrd_path_f = fopen(*initrd_path, "wb"); 585 if (initrd_path_f == NULL) { 586 error_setg_errno(errp, errno, "Failed to open file %s", 587 *initrd_path); 588 goto cleanup; 589 } 590 } 591 592 ptr = g_try_malloc(hdr.section_size); 593 if (!ptr) { 594 error_setg(errp, "Out of memory reading initrd section"); 595 goto cleanup; 596 } 597 598 iov_ptr = g_malloc(sizeof(struct iovec)); 599 iov_ptr->iov_base = ptr; 600 iov_ptr->iov_len = hdr.section_size; 601 602 iov_PCR0 = g_list_append(iov_PCR0, iov_ptr); 603 /* 604 * If it's the first ramdisk, we need to hash it into bootstrap 605 * i.e., iov_PCR1, otherwise we need to hash it into app i.e., 606 * iov_PCR2. 607 */ 608 if (!seen_sections[EIF_SECTION_RAMDISK]) { 609 iov_PCR1 = g_list_append(iov_PCR1, iov_ptr); 610 } else { 611 iov_PCR2 = g_list_append(iov_PCR2, iov_ptr); 612 } 613 614 if (!read_eif_ramdisk(f, initrd_path_f, hdr.section_size, ptr, 615 &crc, errp)) { 616 goto cleanup; 617 } 618 619 break; 620 } 621 case EIF_SECTION_SIGNATURE: 622 *signature_found = true; 623 if (!get_signature_fingerprint_sha384(f, hdr.section_size, 624 fingerprint_sha384, &crc, 625 errp)) { 626 goto cleanup; 627 } 628 break; 629 default: 630 /* other sections including invalid or unknown sections */ 631 { 632 uint8_t *buf; 633 size_t got; 634 uint64_t size = hdr.section_size; 635 buf = g_try_malloc(size); 636 if (!buf) { 637 error_setg(errp, "Out of memory reading unknown section"); 638 goto cleanup; 639 } 640 got = fread(buf, 1, size, f); 641 if ((uint64_t) got != size) { 642 g_free(buf); 643 error_setg(errp, "Failed to read EIF %s section data", 644 section_type_to_string(section_type)); 645 goto cleanup; 646 } 647 crc = crc32(crc, buf, size); 648 g_free(buf); 649 break; 650 } 651 } 652 653 if (section_type < EIF_SECTION_MAX) { 654 seen_sections[section_type] = true; 655 } 656 } 657 658 if (!seen_sections[EIF_SECTION_KERNEL]) { 659 error_setg(errp, "Invalid EIF image. No kernel section."); 660 goto cleanup; 661 } 662 if (!seen_sections[EIF_SECTION_CMDLINE]) { 663 error_setg(errp, "Invalid EIF image. No cmdline section."); 664 goto cleanup; 665 } 666 if (!seen_sections[EIF_SECTION_RAMDISK]) { 667 error_setg(errp, "Invalid EIF image. No ramdisk section."); 668 goto cleanup; 669 } 670 671 if (eif_header.eif_crc32 != crc) { 672 error_setg(errp, "CRC mismatch. Expected %u but header has %u.", 673 crc, eif_header.eif_crc32); 674 goto cleanup; 675 } 676 677 /* 678 * Let's append the initrd file from "-initrd" option if any. Although 679 * we pass the crc pointer to read_eif_ramdisk, it is not useful anymore. 680 * We have already done the crc mismatch check above this code. 681 */ 682 if (machine_initrd) { 683 machine_initrd_f = fopen(machine_initrd, "rb"); 684 if (machine_initrd_f == NULL) { 685 error_setg_errno(errp, errno, "Failed to open initrd file %s", 686 machine_initrd); 687 goto cleanup; 688 } 689 690 machine_initrd_size = get_file_size(machine_initrd_f, errp); 691 if (machine_initrd_size == -1) { 692 goto cleanup; 693 } 694 695 ptr = g_try_malloc(machine_initrd_size); 696 if (!ptr) { 697 error_setg(errp, "Out of memory reading initrd file"); 698 goto cleanup; 699 } 700 701 iov_ptr = g_malloc(sizeof(struct iovec)); 702 iov_ptr->iov_base = ptr; 703 iov_ptr->iov_len = machine_initrd_size; 704 705 iov_PCR0 = g_list_append(iov_PCR0, iov_ptr); 706 iov_PCR2 = g_list_append(iov_PCR2, iov_ptr); 707 708 if (!read_eif_ramdisk(machine_initrd_f, initrd_path_f, 709 machine_initrd_size, ptr, &crc, errp)) { 710 goto cleanup; 711 } 712 } 713 714 if (!get_SHA384_digest(iov_PCR0, image_sha384, errp)) { 715 goto cleanup; 716 } 717 if (!get_SHA384_digest(iov_PCR1, bootstrap_sha384, errp)) { 718 goto cleanup; 719 } 720 if (!get_SHA384_digest(iov_PCR2, app_sha384, errp)) { 721 goto cleanup; 722 } 723 724 /* 725 * We only need to free iov_PCR0 entries because iov_PCR1 and 726 * iov_PCR2 iovec entries are subsets of iov_PCR0 iovec entries. 727 */ 728 g_list_free_full(iov_PCR0, (GDestroyNotify) free_iovec); 729 g_list_free(iov_PCR1); 730 g_list_free(iov_PCR2); 731 fclose(f); 732 fclose(initrd_path_f); 733 safe_fclose(machine_initrd_f); 734 return true; 735 736 cleanup: 737 g_list_free_full(iov_PCR0, (GDestroyNotify) free_iovec); 738 g_list_free(iov_PCR1); 739 g_list_free(iov_PCR2); 740 741 safe_fclose(f); 742 safe_fclose(initrd_path_f); 743 safe_fclose(machine_initrd_f); 744 745 safe_unlink(*kernel_path); 746 g_free(*kernel_path); 747 *kernel_path = NULL; 748 749 safe_unlink(*initrd_path); 750 g_free(*initrd_path); 751 *initrd_path = NULL; 752 753 g_free(*cmdline); 754 *cmdline = NULL; 755 756 return false; 757 } 758