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