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