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