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