1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <ctype.h> 18 #include <errno.h> 19 #include <fcntl.h> 20 #include <inttypes.h> 21 #include <libgen.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <sys/mount.h> 26 #include <sys/stat.h> 27 #include <sys/types.h> 28 #include <sys/wait.h> 29 #include <time.h> 30 #include <unistd.h> 31 32 #include <android-base/file.h> 33 #include <android-base/properties.h> 34 #include <android-base/strings.h> 35 #include <android-base/unique_fd.h> 36 #include <crypto_utils/android_pubkey.h> 37 #include <cutils/properties.h> 38 #include <logwrap/logwrap.h> 39 #include <openssl/obj_mac.h> 40 #include <openssl/rsa.h> 41 #include <openssl/sha.h> 42 43 #include "fec/io.h" 44 45 #include "fs_mgr.h" 46 #include "fs_mgr_priv.h" 47 #include "fs_mgr_priv_dm_ioctl.h" 48 49 #define VERITY_TABLE_RSA_KEY "/verity_key" 50 #define VERITY_TABLE_HASH_IDX 8 51 #define VERITY_TABLE_SALT_IDX 9 52 53 #define VERITY_TABLE_OPT_RESTART "restart_on_corruption" 54 #define VERITY_TABLE_OPT_LOGGING "ignore_corruption" 55 #define VERITY_TABLE_OPT_IGNZERO "ignore_zero_blocks" 56 57 #define VERITY_TABLE_OPT_FEC_FORMAT \ 58 "use_fec_from_device %s fec_start %" PRIu64 " fec_blocks %" PRIu64 \ 59 " fec_roots %u " VERITY_TABLE_OPT_IGNZERO 60 #define VERITY_TABLE_OPT_FEC_ARGS 9 61 62 #define METADATA_MAGIC 0x01564c54 63 #define METADATA_TAG_MAX_LENGTH 63 64 #define METADATA_EOD "eod" 65 66 #define VERITY_LASTSIG_TAG "verity_lastsig" 67 68 #define VERITY_STATE_TAG "verity_state" 69 #define VERITY_STATE_HEADER 0x83c0ae9d 70 #define VERITY_STATE_VERSION 1 71 72 #define VERITY_KMSG_RESTART "dm-verity device corrupted" 73 #define VERITY_KMSG_BUFSIZE 1024 74 75 #define READ_BUF_SIZE 4096 76 77 #define __STRINGIFY(x) #x 78 #define STRINGIFY(x) __STRINGIFY(x) 79 80 struct verity_state { 81 uint32_t header; 82 uint32_t version; 83 int32_t mode; 84 }; 85 86 extern struct fs_info info; 87 88 static RSA *load_key(const char *path) 89 { 90 uint8_t key_data[ANDROID_PUBKEY_ENCODED_SIZE]; 91 92 FILE* f = fopen(path, "r"); 93 if (!f) { 94 LERROR << "Can't open " << path; 95 return NULL; 96 } 97 98 if (!fread(key_data, sizeof(key_data), 1, f)) { 99 LERROR << "Could not read key!"; 100 fclose(f); 101 return NULL; 102 } 103 104 fclose(f); 105 106 RSA* key = NULL; 107 if (!android_pubkey_decode(key_data, sizeof(key_data), &key)) { 108 LERROR << "Could not parse key!"; 109 return NULL; 110 } 111 112 return key; 113 } 114 115 static int verify_table(const uint8_t *signature, size_t signature_size, 116 const char *table, uint32_t table_length) 117 { 118 RSA *key; 119 uint8_t hash_buf[SHA256_DIGEST_LENGTH]; 120 int retval = -1; 121 122 // Hash the table 123 SHA256((uint8_t*)table, table_length, hash_buf); 124 125 // Now get the public key from the keyfile 126 key = load_key(VERITY_TABLE_RSA_KEY); 127 if (!key) { 128 LERROR << "Couldn't load verity keys"; 129 goto out; 130 } 131 132 // verify the result 133 if (!RSA_verify(NID_sha256, hash_buf, sizeof(hash_buf), signature, 134 signature_size, key)) { 135 LERROR << "Couldn't verify table"; 136 goto out; 137 } 138 139 retval = 0; 140 141 out: 142 RSA_free(key); 143 return retval; 144 } 145 146 static int verify_verity_signature(const struct fec_verity_metadata& verity) 147 { 148 if (verify_table(verity.signature, sizeof(verity.signature), 149 verity.table, verity.table_length) == 0 || 150 verify_table(verity.ecc_signature, sizeof(verity.ecc_signature), 151 verity.table, verity.table_length) == 0) { 152 return 0; 153 } 154 155 return -1; 156 } 157 158 static int invalidate_table(char *table, size_t table_length) 159 { 160 size_t n = 0; 161 size_t idx = 0; 162 size_t cleared = 0; 163 164 while (n < table_length) { 165 if (table[n++] == ' ') { 166 ++idx; 167 } 168 169 if (idx != VERITY_TABLE_HASH_IDX && idx != VERITY_TABLE_SALT_IDX) { 170 continue; 171 } 172 173 while (n < table_length && table[n] != ' ') { 174 table[n++] = '0'; 175 } 176 177 if (++cleared == 2) { 178 return 0; 179 } 180 } 181 182 return -1; 183 } 184 185 struct verity_table_params { 186 char *table; 187 int mode; 188 struct fec_ecc_metadata ecc; 189 const char *ecc_dev; 190 }; 191 192 typedef bool (*format_verity_table_func)(char *buf, const size_t bufsize, 193 const struct verity_table_params *params); 194 195 static bool format_verity_table(char *buf, const size_t bufsize, 196 const struct verity_table_params *params) 197 { 198 const char *mode_flag = NULL; 199 int res = -1; 200 201 if (params->mode == VERITY_MODE_RESTART) { 202 mode_flag = VERITY_TABLE_OPT_RESTART; 203 } else if (params->mode == VERITY_MODE_LOGGING) { 204 mode_flag = VERITY_TABLE_OPT_LOGGING; 205 } 206 207 if (params->ecc.valid) { 208 if (mode_flag) { 209 res = snprintf(buf, bufsize, 210 "%s %u %s " VERITY_TABLE_OPT_FEC_FORMAT, 211 params->table, 1 + VERITY_TABLE_OPT_FEC_ARGS, mode_flag, params->ecc_dev, 212 params->ecc.start / FEC_BLOCKSIZE, params->ecc.blocks, params->ecc.roots); 213 } else { 214 res = snprintf(buf, bufsize, 215 "%s %u " VERITY_TABLE_OPT_FEC_FORMAT, 216 params->table, VERITY_TABLE_OPT_FEC_ARGS, params->ecc_dev, 217 params->ecc.start / FEC_BLOCKSIZE, params->ecc.blocks, params->ecc.roots); 218 } 219 } else if (mode_flag) { 220 res = snprintf(buf, bufsize, "%s 2 " VERITY_TABLE_OPT_IGNZERO " %s", params->table, 221 mode_flag); 222 } else { 223 res = snprintf(buf, bufsize, "%s 1 " VERITY_TABLE_OPT_IGNZERO, params->table); 224 } 225 226 if (res < 0 || (size_t)res >= bufsize) { 227 LERROR << "Error building verity table; insufficient buffer size?"; 228 return false; 229 } 230 231 return true; 232 } 233 234 static bool format_legacy_verity_table(char *buf, const size_t bufsize, 235 const struct verity_table_params *params) 236 { 237 int res; 238 239 if (params->mode == VERITY_MODE_EIO) { 240 res = strlcpy(buf, params->table, bufsize); 241 } else { 242 res = snprintf(buf, bufsize, "%s %d", params->table, params->mode); 243 } 244 245 if (res < 0 || (size_t)res >= bufsize) { 246 LERROR << "Error building verity table; insufficient buffer size?"; 247 return false; 248 } 249 250 return true; 251 } 252 253 static int load_verity_table(struct dm_ioctl *io, const std::string &name, 254 uint64_t device_size, int fd, 255 const struct verity_table_params *params, format_verity_table_func format) 256 { 257 char *verity_params; 258 char *buffer = (char*) io; 259 size_t bufsize; 260 261 fs_mgr_verity_ioctl_init(io, name, DM_STATUS_TABLE_FLAG); 262 263 struct dm_target_spec *tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)]; 264 265 // set tgt arguments 266 io->target_count = 1; 267 tgt->status = 0; 268 tgt->sector_start = 0; 269 tgt->length = device_size / 512; 270 strcpy(tgt->target_type, "verity"); 271 272 // build the verity params 273 verity_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec); 274 bufsize = DM_BUF_SIZE - (verity_params - buffer); 275 276 if (!format(verity_params, bufsize, params)) { 277 LERROR << "Failed to format verity parameters"; 278 return -1; 279 } 280 281 LINFO << "loading verity table: '" << verity_params << "'"; 282 283 // set next target boundary 284 verity_params += strlen(verity_params) + 1; 285 verity_params = (char*)(((uintptr_t)verity_params + 7) & ~7); 286 tgt->next = verity_params - buffer; 287 288 // send the ioctl to load the verity table 289 if (ioctl(fd, DM_TABLE_LOAD, io)) { 290 PERROR << "Error loading verity table"; 291 return -1; 292 } 293 294 return 0; 295 } 296 297 static int check_verity_restart(const char *fname) 298 { 299 char buffer[VERITY_KMSG_BUFSIZE + 1]; 300 int fd; 301 int rc = 0; 302 ssize_t size; 303 struct stat s; 304 305 fd = TEMP_FAILURE_RETRY(open(fname, O_RDONLY | O_CLOEXEC)); 306 307 if (fd == -1) { 308 if (errno != ENOENT) { 309 PERROR << "Failed to open " << fname; 310 } 311 goto out; 312 } 313 314 if (fstat(fd, &s) == -1) { 315 PERROR << "Failed to fstat " << fname; 316 goto out; 317 } 318 319 size = VERITY_KMSG_BUFSIZE; 320 321 if (size > s.st_size) { 322 size = s.st_size; 323 } 324 325 if (lseek(fd, s.st_size - size, SEEK_SET) == -1) { 326 PERROR << "Failed to lseek " << (intmax_t)(s.st_size - size) << " " << fname; 327 goto out; 328 } 329 330 if (!android::base::ReadFully(fd, buffer, size)) { 331 PERROR << "Failed to read " << size << " bytes from " << fname; 332 goto out; 333 } 334 335 buffer[size] = '\0'; 336 337 if (strstr(buffer, VERITY_KMSG_RESTART) != NULL) { 338 rc = 1; 339 } 340 341 out: 342 if (fd != -1) { 343 close(fd); 344 } 345 346 return rc; 347 } 348 349 static int was_verity_restart() 350 { 351 static const char* files[] = { 352 // clang-format off 353 "/sys/fs/pstore/console-ramoops-0", 354 "/sys/fs/pstore/console-ramoops", 355 "/proc/last_kmsg", 356 NULL 357 // clang-format on 358 }; 359 int i; 360 361 for (i = 0; files[i]; ++i) { 362 if (check_verity_restart(files[i])) { 363 return 1; 364 } 365 } 366 367 return 0; 368 } 369 370 static int metadata_add(FILE *fp, long start, const char *tag, 371 unsigned int length, off64_t *offset) 372 { 373 if (fseek(fp, start, SEEK_SET) < 0 || 374 fprintf(fp, "%s %u\n", tag, length) < 0) { 375 return -1; 376 } 377 378 *offset = ftell(fp); 379 380 if (fseek(fp, length, SEEK_CUR) < 0 || 381 fprintf(fp, METADATA_EOD " 0\n") < 0) { 382 return -1; 383 } 384 385 return 0; 386 } 387 388 static int metadata_find(const char *fname, const char *stag, 389 unsigned int slength, off64_t *offset) 390 { 391 FILE *fp = NULL; 392 char tag[METADATA_TAG_MAX_LENGTH + 1]; 393 int rc = -1; 394 int n; 395 long start = 0x4000; /* skip cryptfs metadata area */ 396 uint32_t magic; 397 unsigned int length = 0; 398 399 if (!fname) { 400 return -1; 401 } 402 403 fp = fopen(fname, "r+"); 404 405 if (!fp) { 406 PERROR << "Failed to open " << fname; 407 goto out; 408 } 409 410 /* check magic */ 411 if (fseek(fp, start, SEEK_SET) < 0 || 412 fread(&magic, sizeof(magic), 1, fp) != 1) { 413 PERROR << "Failed to read magic from " << fname; 414 goto out; 415 } 416 417 if (magic != METADATA_MAGIC) { 418 magic = METADATA_MAGIC; 419 420 if (fseek(fp, start, SEEK_SET) < 0 || 421 fwrite(&magic, sizeof(magic), 1, fp) != 1) { 422 PERROR << "Failed to write magic to " << fname; 423 goto out; 424 } 425 426 rc = metadata_add(fp, start + sizeof(magic), stag, slength, offset); 427 if (rc < 0) { 428 PERROR << "Failed to add metadata to " << fname; 429 } 430 431 goto out; 432 } 433 434 start += sizeof(magic); 435 436 while (1) { 437 n = fscanf(fp, "%" STRINGIFY(METADATA_TAG_MAX_LENGTH) "s %u\n", 438 tag, &length); 439 440 if (n == 2 && strcmp(tag, METADATA_EOD)) { 441 /* found a tag */ 442 start = ftell(fp); 443 444 if (!strcmp(tag, stag) && length == slength) { 445 *offset = start; 446 rc = 0; 447 goto out; 448 } 449 450 start += length; 451 452 if (fseek(fp, length, SEEK_CUR) < 0) { 453 PERROR << "Failed to seek " << fname; 454 goto out; 455 } 456 } else { 457 rc = metadata_add(fp, start, stag, slength, offset); 458 if (rc < 0) { 459 PERROR << "Failed to write metadata to " << fname; 460 } 461 goto out; 462 } 463 } 464 465 out: 466 if (fp) { 467 fflush(fp); 468 fclose(fp); 469 } 470 471 return rc; 472 } 473 474 static int write_verity_state(const char *fname, off64_t offset, int32_t mode) 475 { 476 int fd; 477 int rc = -1; 478 struct verity_state s = { VERITY_STATE_HEADER, VERITY_STATE_VERSION, mode }; 479 480 fd = TEMP_FAILURE_RETRY(open(fname, O_WRONLY | O_SYNC | O_CLOEXEC)); 481 482 if (fd == -1) { 483 PERROR << "Failed to open " << fname; 484 goto out; 485 } 486 487 if (TEMP_FAILURE_RETRY(pwrite64(fd, &s, sizeof(s), offset)) != sizeof(s)) { 488 PERROR << "Failed to write " << sizeof(s) << " bytes to " << fname 489 << " to offset " << offset; 490 goto out; 491 } 492 493 rc = 0; 494 495 out: 496 if (fd != -1) { 497 close(fd); 498 } 499 500 return rc; 501 } 502 503 static int read_verity_state(const char *fname, off64_t offset, int *mode) 504 { 505 int fd = -1; 506 int rc = -1; 507 struct verity_state s; 508 509 fd = TEMP_FAILURE_RETRY(open(fname, O_RDONLY | O_CLOEXEC)); 510 511 if (fd == -1) { 512 PERROR << "Failed to open " << fname; 513 goto out; 514 } 515 516 if (TEMP_FAILURE_RETRY(pread64(fd, &s, sizeof(s), offset)) != sizeof(s)) { 517 PERROR << "Failed to read " << sizeof(s) << " bytes from " << fname 518 << " offset " << offset; 519 goto out; 520 } 521 522 if (s.header != VERITY_STATE_HEADER) { 523 /* space allocated, but no state written. write default state */ 524 *mode = VERITY_MODE_DEFAULT; 525 rc = write_verity_state(fname, offset, *mode); 526 goto out; 527 } 528 529 if (s.version != VERITY_STATE_VERSION) { 530 LERROR << "Unsupported verity state version (" << s.version << ")"; 531 goto out; 532 } 533 534 if (s.mode < VERITY_MODE_EIO || 535 s.mode > VERITY_MODE_LAST) { 536 LERROR << "Unsupported verity mode (" << s.mode << ")"; 537 goto out; 538 } 539 540 *mode = s.mode; 541 rc = 0; 542 543 out: 544 if (fd != -1) { 545 close(fd); 546 } 547 548 return rc; 549 } 550 551 static int read_partition(const char *path, uint64_t size) 552 { 553 char buf[READ_BUF_SIZE]; 554 ssize_t size_read; 555 android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC))); 556 557 if (fd == -1) { 558 PERROR << "Failed to open " << path; 559 return -errno; 560 } 561 562 while (size) { 563 size_read = TEMP_FAILURE_RETRY(read(fd, buf, READ_BUF_SIZE)); 564 if (size_read == -1) { 565 PERROR << "Error in reading partition " << path; 566 return -errno; 567 } 568 size -= size_read; 569 } 570 571 return 0; 572 } 573 574 static int compare_last_signature(struct fstab_rec *fstab, int *match) 575 { 576 char tag[METADATA_TAG_MAX_LENGTH + 1]; 577 int fd = -1; 578 int rc = -1; 579 off64_t offset = 0; 580 struct fec_handle *f = NULL; 581 struct fec_verity_metadata verity; 582 uint8_t curr[SHA256_DIGEST_LENGTH]; 583 uint8_t prev[SHA256_DIGEST_LENGTH]; 584 585 *match = 1; 586 587 if (fec_open(&f, fstab->blk_device, O_RDONLY, FEC_VERITY_DISABLE, 588 FEC_DEFAULT_ROOTS) == -1) { 589 PERROR << "Failed to open '" << fstab->blk_device << "'"; 590 return rc; 591 } 592 593 // read verity metadata 594 if (fec_verity_get_metadata(f, &verity) == -1) { 595 PERROR << "Failed to get verity metadata '" << fstab->blk_device << "'"; 596 goto out; 597 } 598 599 SHA256(verity.signature, sizeof(verity.signature), curr); 600 601 if (snprintf(tag, sizeof(tag), VERITY_LASTSIG_TAG "_%s", 602 basename(fstab->mount_point)) >= (int)sizeof(tag)) { 603 LERROR << "Metadata tag name too long for " << fstab->mount_point; 604 goto out; 605 } 606 607 if (metadata_find(fstab->verity_loc, tag, SHA256_DIGEST_LENGTH, 608 &offset) < 0) { 609 goto out; 610 } 611 612 fd = TEMP_FAILURE_RETRY(open(fstab->verity_loc, O_RDWR | O_SYNC | O_CLOEXEC)); 613 614 if (fd == -1) { 615 PERROR << "Failed to open " << fstab->verity_loc; 616 goto out; 617 } 618 619 if (TEMP_FAILURE_RETRY(pread64(fd, prev, sizeof(prev), 620 offset)) != sizeof(prev)) { 621 PERROR << "Failed to read " << sizeof(prev) << " bytes from " 622 << fstab->verity_loc << " offset " << offset; 623 goto out; 624 } 625 626 *match = !memcmp(curr, prev, SHA256_DIGEST_LENGTH); 627 628 if (!*match) { 629 /* update current signature hash */ 630 if (TEMP_FAILURE_RETRY(pwrite64(fd, curr, sizeof(curr), 631 offset)) != sizeof(curr)) { 632 PERROR << "Failed to write " << sizeof(curr) << " bytes to " 633 << fstab->verity_loc << " offset " << offset; 634 goto out; 635 } 636 } 637 638 rc = 0; 639 640 out: 641 fec_close(f); 642 return rc; 643 } 644 645 static int get_verity_state_offset(struct fstab_rec *fstab, off64_t *offset) 646 { 647 char tag[METADATA_TAG_MAX_LENGTH + 1]; 648 649 if (snprintf(tag, sizeof(tag), VERITY_STATE_TAG "_%s", 650 basename(fstab->mount_point)) >= (int)sizeof(tag)) { 651 LERROR << "Metadata tag name too long for " << fstab->mount_point; 652 return -1; 653 } 654 655 return metadata_find(fstab->verity_loc, tag, sizeof(struct verity_state), 656 offset); 657 } 658 659 int load_verity_state(struct fstab_rec* fstab, int* mode) { 660 int match = 0; 661 off64_t offset = 0; 662 663 /* unless otherwise specified, use EIO mode */ 664 *mode = VERITY_MODE_EIO; 665 666 /* use the kernel parameter if set */ 667 std::string veritymode; 668 if (fs_mgr_get_boot_config("veritymode", &veritymode)) { 669 if (veritymode == "enforcing") { 670 *mode = VERITY_MODE_DEFAULT; 671 } 672 return 0; 673 } 674 675 if (get_verity_state_offset(fstab, &offset) < 0) { 676 /* fall back to stateless behavior */ 677 return 0; 678 } 679 680 if (was_verity_restart()) { 681 /* device was restarted after dm-verity detected a corrupted 682 * block, so use EIO mode */ 683 return write_verity_state(fstab->verity_loc, offset, *mode); 684 } 685 686 if (!compare_last_signature(fstab, &match) && !match) { 687 /* partition has been reflashed, reset dm-verity state */ 688 *mode = VERITY_MODE_DEFAULT; 689 return write_verity_state(fstab->verity_loc, offset, *mode); 690 } 691 692 return read_verity_state(fstab->verity_loc, offset, mode); 693 } 694 695 // Update the verity table using the actual block device path. 696 // Two cases: 697 // Case-1: verity table is shared for devices with different by-name prefix. 698 // Example: 699 // verity table token: /dev/block/bootdevice/by-name/vendor 700 // blk_device-1 (non-A/B): /dev/block/platform/soc.0/7824900.sdhci/by-name/vendor 701 // blk_device-2 (A/B): /dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor_a 702 // 703 // Case-2: append A/B suffix in the verity table. 704 // Example: 705 // verity table token: /dev/block/platform/soc.0/7824900.sdhci/by-name/vendor 706 // blk_device: /dev/block/platform/soc.0/7824900.sdhci/by-name/vendor_a 707 static void update_verity_table_blk_device(const std::string& blk_device, char** table, 708 bool slot_select) { 709 bool updated = false; 710 std::string result, ab_suffix; 711 auto tokens = android::base::Split(*table, " "); 712 713 // If slot_select is set, it means blk_device is already updated with ab_suffix. 714 if (slot_select) ab_suffix = fs_mgr_get_slot_suffix(); 715 716 for (const auto& token : tokens) { 717 std::string new_token; 718 if (android::base::StartsWith(token, "/dev/block/")) { 719 if (token == blk_device) return; // no need to update if they're already the same. 720 std::size_t found1 = blk_device.find("by-name"); 721 std::size_t found2 = token.find("by-name"); 722 if (found1 != std::string::npos && found2 != std::string::npos && 723 blk_device.substr(found1) == token.substr(found2) + ab_suffix) { 724 new_token = blk_device; 725 } 726 } 727 728 if (!new_token.empty()) { 729 updated = true; 730 LINFO << "Verity table: updated block device from '" << token << "' to '" << new_token 731 << "'"; 732 } else { 733 new_token = token; 734 } 735 736 if (result.empty()) { 737 result = new_token; 738 } else { 739 result += " " + new_token; 740 } 741 } 742 743 if (!updated) { 744 return; 745 } 746 747 free(*table); 748 *table = strdup(result.c_str()); 749 } 750 751 // prepares the verity enabled (MF_VERIFY / MF_VERIFYATBOOT) fstab record for 752 // mount. The 'wait_for_verity_dev' parameter makes this function wait for the 753 // verity device to get created before return 754 int fs_mgr_setup_verity(struct fstab_rec *fstab, bool wait_for_verity_dev) 755 { 756 int retval = FS_MGR_SETUP_VERITY_FAIL; 757 int fd = -1; 758 std::string verity_blk_name; 759 struct fec_handle *f = NULL; 760 struct fec_verity_metadata verity; 761 struct verity_table_params params = { .table = NULL }; 762 763 alignas(dm_ioctl) char buffer[DM_BUF_SIZE]; 764 struct dm_ioctl *io = (struct dm_ioctl *) buffer; 765 const std::string mount_point(basename(fstab->mount_point)); 766 bool verified_at_boot = false; 767 768 if (fec_open(&f, fstab->blk_device, O_RDONLY, FEC_VERITY_DISABLE, 769 FEC_DEFAULT_ROOTS) < 0) { 770 PERROR << "Failed to open '" << fstab->blk_device << "'"; 771 return retval; 772 } 773 774 // read verity metadata 775 if (fec_verity_get_metadata(f, &verity) < 0) { 776 PERROR << "Failed to get verity metadata '" << fstab->blk_device << "'"; 777 // Allow verity disabled when the device is unlocked without metadata 778 if (fs_mgr_is_device_unlocked()) { 779 retval = FS_MGR_SETUP_VERITY_SKIPPED; 780 LWARNING << "Allow invalid metadata when the device is unlocked"; 781 } 782 goto out; 783 } 784 785 #ifdef ALLOW_ADBD_DISABLE_VERITY 786 if (verity.disabled) { 787 retval = FS_MGR_SETUP_VERITY_DISABLED; 788 LINFO << "Attempt to cleanly disable verity - only works in USERDEBUG/ENG"; 789 goto out; 790 } 791 #endif 792 793 // read ecc metadata 794 if (fec_ecc_get_metadata(f, ¶ms.ecc) < 0) { 795 params.ecc.valid = false; 796 } 797 798 params.ecc_dev = fstab->blk_device; 799 800 // get the device mapper fd 801 if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) { 802 PERROR << "Error opening device mapper"; 803 goto out; 804 } 805 806 // create the device 807 if (!fs_mgr_create_verity_device(io, mount_point, fd)) { 808 LERROR << "Couldn't create verity device!"; 809 goto out; 810 } 811 812 // get the name of the device file 813 if (!fs_mgr_get_verity_device_name(io, mount_point, fd, &verity_blk_name)) { 814 LERROR << "Couldn't get verity device number!"; 815 goto out; 816 } 817 818 if (load_verity_state(fstab, ¶ms.mode) < 0) { 819 /* if accessing or updating the state failed, switch to the default 820 * safe mode. This makes sure the device won't end up in an endless 821 * restart loop, and no corrupted data will be exposed to userspace 822 * without a warning. */ 823 params.mode = VERITY_MODE_EIO; 824 } 825 826 if (!verity.table) { 827 goto out; 828 } 829 830 params.table = strdup(verity.table); 831 if (!params.table) { 832 goto out; 833 } 834 835 // verify the signature on the table 836 if (verify_verity_signature(verity) < 0) { 837 // Allow signature verification error when the device is unlocked 838 if (fs_mgr_is_device_unlocked()) { 839 retval = FS_MGR_SETUP_VERITY_SKIPPED; 840 LWARNING << "Allow signature verification error when the device is unlocked"; 841 goto out; 842 } 843 if (params.mode == VERITY_MODE_LOGGING) { 844 // the user has been warned, allow mounting without dm-verity 845 retval = FS_MGR_SETUP_VERITY_SKIPPED; 846 goto out; 847 } 848 849 // invalidate root hash and salt to trigger device-specific recovery 850 if (invalidate_table(params.table, verity.table_length) < 0) { 851 goto out; 852 } 853 } 854 855 LINFO << "Enabling dm-verity for " << mount_point.c_str() 856 << " (mode " << params.mode << ")"; 857 858 // Update the verity params using the actual block device path 859 update_verity_table_blk_device(fstab->blk_device, ¶ms.table, 860 fstab->fs_mgr_flags & MF_SLOTSELECT); 861 862 // load the verity mapping table 863 if (load_verity_table(io, mount_point, verity.data_size, fd, ¶ms, 864 format_verity_table) == 0) { 865 goto loaded; 866 } 867 868 if (params.ecc.valid) { 869 // kernel may not support error correction, try without 870 LINFO << "Disabling error correction for " << mount_point.c_str(); 871 params.ecc.valid = false; 872 873 if (load_verity_table(io, mount_point, verity.data_size, fd, ¶ms, 874 format_verity_table) == 0) { 875 goto loaded; 876 } 877 } 878 879 // try the legacy format for backwards compatibility 880 if (load_verity_table(io, mount_point, verity.data_size, fd, ¶ms, 881 format_legacy_verity_table) == 0) { 882 goto loaded; 883 } 884 885 if (params.mode != VERITY_MODE_EIO) { 886 // as a last resort, EIO mode should always be supported 887 LINFO << "Falling back to EIO mode for " << mount_point.c_str(); 888 params.mode = VERITY_MODE_EIO; 889 890 if (load_verity_table(io, mount_point, verity.data_size, fd, ¶ms, 891 format_legacy_verity_table) == 0) { 892 goto loaded; 893 } 894 } 895 896 LERROR << "Failed to load verity table for " << mount_point.c_str(); 897 goto out; 898 899 loaded: 900 901 // activate the device 902 if (!fs_mgr_resume_verity_table(io, mount_point, fd)) { 903 goto out; 904 } 905 906 // mark the underlying block device as read-only 907 fs_mgr_set_blk_ro(fstab->blk_device); 908 909 // Verify the entire partition in one go 910 // If there is an error, allow it to mount as a normal verity partition. 911 if (fstab->fs_mgr_flags & MF_VERIFYATBOOT) { 912 LINFO << "Verifying partition " << fstab->blk_device << " at boot"; 913 int err = read_partition(verity_blk_name.c_str(), verity.data_size); 914 if (!err) { 915 LINFO << "Verified verity partition " 916 << fstab->blk_device << " at boot"; 917 verified_at_boot = true; 918 } 919 } 920 921 // assign the new verity block device as the block device 922 if (!verified_at_boot) { 923 free(fstab->blk_device); 924 fstab->blk_device = strdup(verity_blk_name.c_str()); 925 } else if (!fs_mgr_destroy_verity_device(io, mount_point, fd)) { 926 LERROR << "Failed to remove verity device " << mount_point.c_str(); 927 goto out; 928 } 929 930 // make sure we've set everything up properly 931 if (wait_for_verity_dev && !fs_mgr_wait_for_file(fstab->blk_device, 1s)) { 932 goto out; 933 } 934 935 retval = FS_MGR_SETUP_VERITY_SUCCESS; 936 937 out: 938 if (fd != -1) { 939 close(fd); 940 } 941 942 fec_close(f); 943 free(params.table); 944 945 return retval; 946 } 947