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