1 /* 2 * Copyright (C) 2012 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 <dirent.h> 19 #include <errno.h> 20 #include <fcntl.h> 21 #include <libgen.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <sys/ioctl.h> 26 #include <sys/mount.h> 27 #include <sys/stat.h> 28 #include <sys/swap.h> 29 #include <sys/types.h> 30 #include <sys/wait.h> 31 #include <time.h> 32 #include <unistd.h> 33 34 #include <memory> 35 36 #include <android-base/file.h> 37 #include <android-base/properties.h> 38 #include <android-base/stringprintf.h> 39 #include <android-base/unique_fd.h> 40 #include <cutils/android_reboot.h> 41 #include <cutils/partition_utils.h> 42 #include <cutils/properties.h> 43 #include <ext4_utils/ext4.h> 44 #include <ext4_utils/ext4_crypt_init_extensions.h> 45 #include <ext4_utils/ext4_sb.h> 46 #include <ext4_utils/ext4_utils.h> 47 #include <ext4_utils/wipe.h> 48 #include <linux/fs.h> 49 #include <linux/loop.h> 50 #include <linux/magic.h> 51 #include <log/log_properties.h> 52 #include <logwrap/logwrap.h> 53 54 #include "fs_mgr.h" 55 #include "fs_mgr_avb.h" 56 #include "fs_mgr_priv.h" 57 #include "fs_mgr_priv_dm_ioctl.h" 58 59 #define KEY_LOC_PROP "ro.crypto.keyfile.userdata" 60 #define KEY_IN_FOOTER "footer" 61 62 #define E2FSCK_BIN "/system/bin/e2fsck" 63 #define F2FS_FSCK_BIN "/system/bin/fsck.f2fs" 64 #define MKSWAP_BIN "/system/bin/mkswap" 65 #define TUNE2FS_BIN "/system/bin/tune2fs" 66 67 #define FSCK_LOG_FILE "/dev/fscklogs/log" 68 69 #define ZRAM_CONF_DEV "/sys/block/zram0/disksize" 70 #define ZRAM_CONF_MCS "/sys/block/zram0/max_comp_streams" 71 72 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) 73 74 // record fs stat 75 enum FsStatFlags { 76 FS_STAT_IS_EXT4 = 0x0001, 77 FS_STAT_NEW_IMAGE_VERSION = 0x0002, 78 FS_STAT_E2FSCK_F_ALWAYS = 0x0004, 79 FS_STAT_UNCLEAN_SHUTDOWN = 0x0008, 80 FS_STAT_QUOTA_ENABLED = 0x0010, 81 FS_STAT_TUNE2FS_FAILED = 0x0020, 82 FS_STAT_RO_MOUNT_FAILED = 0x0040, 83 FS_STAT_RO_UNMOUNT_FAILED = 0x0080, 84 FS_STAT_FULL_MOUNT_FAILED = 0x0100, 85 FS_STAT_E2FSCK_FAILED = 0x0200, 86 FS_STAT_E2FSCK_FS_FIXED = 0x0400, 87 FS_STAT_EXT4_INVALID_MAGIC = 0x0800, 88 }; 89 90 /* 91 * gettime() - returns the time in seconds of the system's monotonic clock or 92 * zero on error. 93 */ 94 static time_t gettime(void) 95 { 96 struct timespec ts; 97 int ret; 98 99 ret = clock_gettime(CLOCK_MONOTONIC, &ts); 100 if (ret < 0) { 101 PERROR << "clock_gettime(CLOCK_MONOTONIC) failed"; 102 return 0; 103 } 104 105 return ts.tv_sec; 106 } 107 108 static int wait_for_file(const char *filename, int timeout) 109 { 110 struct stat info; 111 time_t timeout_time = gettime() + timeout; 112 int ret = -1; 113 114 while (gettime() < timeout_time && ((ret = stat(filename, &info)) < 0)) 115 usleep(10000); 116 117 return ret; 118 } 119 120 static void log_fs_stat(const char* blk_device, int fs_stat) 121 { 122 if ((fs_stat & FS_STAT_IS_EXT4) == 0) return; // only log ext4 123 std::string msg = android::base::StringPrintf("\nfs_stat,%s,0x%x\n", blk_device, fs_stat); 124 android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(FSCK_LOG_FILE, O_WRONLY | O_CLOEXEC | 125 O_APPEND | O_CREAT, 0664))); 126 if (fd == -1 || !android::base::WriteStringToFd(msg, fd)) { 127 LWARNING << __FUNCTION__ << "() cannot log " << msg; 128 } 129 } 130 131 static bool should_force_check(int fs_stat) { 132 return fs_stat & (FS_STAT_E2FSCK_F_ALWAYS | FS_STAT_UNCLEAN_SHUTDOWN | FS_STAT_QUOTA_ENABLED | 133 FS_STAT_TUNE2FS_FAILED | FS_STAT_RO_MOUNT_FAILED | FS_STAT_RO_UNMOUNT_FAILED | 134 FS_STAT_FULL_MOUNT_FAILED | FS_STAT_E2FSCK_FAILED); 135 } 136 137 static void check_fs(const char *blk_device, char *fs_type, char *target, int *fs_stat) 138 { 139 int status; 140 int ret; 141 long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID; 142 char tmpmnt_opts[64] = "errors=remount-ro"; 143 const char* e2fsck_argv[] = {E2FSCK_BIN, "-y", blk_device}; 144 const char* e2fsck_forced_argv[] = {E2FSCK_BIN, "-f", "-y", blk_device}; 145 146 /* Check for the types of filesystems we know how to check */ 147 if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) { 148 if (*fs_stat & FS_STAT_EXT4_INVALID_MAGIC) { // will fail, so do not try 149 return; 150 } 151 /* 152 * First try to mount and unmount the filesystem. We do this because 153 * the kernel is more efficient than e2fsck in running the journal and 154 * processing orphaned inodes, and on at least one device with a 155 * performance issue in the emmc firmware, it can take e2fsck 2.5 minutes 156 * to do what the kernel does in about a second. 157 * 158 * After mounting and unmounting the filesystem, run e2fsck, and if an 159 * error is recorded in the filesystem superblock, e2fsck will do a full 160 * check. Otherwise, it does nothing. If the kernel cannot mount the 161 * filesytsem due to an error, e2fsck is still run to do a full check 162 * fix the filesystem. 163 */ 164 if (!(*fs_stat & FS_STAT_FULL_MOUNT_FAILED)) { // already tried if full mount failed 165 errno = 0; 166 if (!strcmp(fs_type, "ext4")) { 167 // This option is only valid with ext4 168 strlcat(tmpmnt_opts, ",nomblk_io_submit", sizeof(tmpmnt_opts)); 169 } 170 ret = mount(blk_device, target, fs_type, tmpmnt_flags, tmpmnt_opts); 171 PINFO << __FUNCTION__ << "(): mount(" << blk_device << "," << target << "," << fs_type 172 << ")=" << ret; 173 if (!ret) { 174 bool umounted = false; 175 int retry_count = 5; 176 while (retry_count-- > 0) { 177 umounted = umount(target) == 0; 178 if (umounted) { 179 LINFO << __FUNCTION__ << "(): unmount(" << target << ") succeeded"; 180 break; 181 } 182 PERROR << __FUNCTION__ << "(): umount(" << target << ") failed"; 183 if (retry_count) sleep(1); 184 } 185 if (!umounted) { 186 // boot may fail but continue and leave it to later stage for now. 187 PERROR << __FUNCTION__ << "(): umount(" << target << ") timed out"; 188 *fs_stat |= FS_STAT_RO_UNMOUNT_FAILED; 189 } 190 } else { 191 *fs_stat |= FS_STAT_RO_MOUNT_FAILED; 192 } 193 } 194 195 /* 196 * Some system images do not have e2fsck for licensing reasons 197 * (e.g. recent SDK system images). Detect these and skip the check. 198 */ 199 if (access(E2FSCK_BIN, X_OK)) { 200 LINFO << "Not running " << E2FSCK_BIN << " on " << blk_device 201 << " (executable not in system image)"; 202 } else { 203 LINFO << "Running " << E2FSCK_BIN << " on " << blk_device; 204 if (should_force_check(*fs_stat)) { 205 ret = android_fork_execvp_ext( 206 ARRAY_SIZE(e2fsck_forced_argv), const_cast<char**>(e2fsck_forced_argv), &status, 207 true, LOG_KLOG | LOG_FILE, true, const_cast<char*>(FSCK_LOG_FILE), NULL, 0); 208 } else { 209 ret = android_fork_execvp_ext( 210 ARRAY_SIZE(e2fsck_argv), const_cast<char**>(e2fsck_argv), &status, true, 211 LOG_KLOG | LOG_FILE, true, const_cast<char*>(FSCK_LOG_FILE), NULL, 0); 212 } 213 214 if (ret < 0) { 215 /* No need to check for error in fork, we can't really handle it now */ 216 LERROR << "Failed trying to run " << E2FSCK_BIN; 217 *fs_stat |= FS_STAT_E2FSCK_FAILED; 218 } else if (status != 0) { 219 LINFO << "e2fsck returned status 0x" << std::hex << status; 220 *fs_stat |= FS_STAT_E2FSCK_FS_FIXED; 221 } 222 } 223 } else if (!strcmp(fs_type, "f2fs")) { 224 const char *f2fs_fsck_argv[] = { 225 F2FS_FSCK_BIN, 226 "-a", 227 blk_device 228 }; 229 LINFO << "Running " << F2FS_FSCK_BIN << " -a " << blk_device; 230 231 ret = android_fork_execvp_ext(ARRAY_SIZE(f2fs_fsck_argv), 232 const_cast<char **>(f2fs_fsck_argv), 233 &status, true, LOG_KLOG | LOG_FILE, 234 true, const_cast<char *>(FSCK_LOG_FILE), 235 NULL, 0); 236 if (ret < 0) { 237 /* No need to check for error in fork, we can't really handle it now */ 238 LERROR << "Failed trying to run " << F2FS_FSCK_BIN; 239 } 240 } 241 242 return; 243 } 244 245 /* Function to read the primary superblock */ 246 static int read_super_block(int fd, struct ext4_super_block *sb) 247 { 248 off64_t ret; 249 250 ret = lseek64(fd, 1024, SEEK_SET); 251 if (ret < 0) 252 return ret; 253 254 ret = read(fd, sb, sizeof(*sb)); 255 if (ret < 0) 256 return ret; 257 if (ret != sizeof(*sb)) 258 return ret; 259 260 return 0; 261 } 262 263 static ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es) 264 { 265 return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) | 266 le32_to_cpu(es->s_blocks_count_lo); 267 } 268 269 static ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es) 270 { 271 return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) | 272 le32_to_cpu(es->s_r_blocks_count_lo); 273 } 274 275 static int do_quota_with_shutdown_check(char *blk_device, char *fs_type, 276 struct fstab_rec *rec, int *fs_stat) 277 { 278 int force_check = 0; 279 if (!strcmp(fs_type, "ext4")) { 280 /* 281 * Some system images do not have tune2fs for licensing reasons 282 * Detect these and skip reserve blocks. 283 */ 284 if (access(TUNE2FS_BIN, X_OK)) { 285 LERROR << "Not running " << TUNE2FS_BIN << " on " 286 << blk_device << " (executable not in system image)"; 287 } else { 288 const char* arg1 = nullptr; 289 const char* arg2 = nullptr; 290 int status = 0; 291 int ret = 0; 292 android::base::unique_fd fd( 293 TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC))); 294 if (fd >= 0) { 295 struct ext4_super_block sb; 296 ret = read_super_block(fd, &sb); 297 if (ret < 0) { 298 PERROR << "Can't read '" << blk_device << "' super block"; 299 return force_check; 300 } 301 if (sb.s_magic != EXT4_SUPER_MAGIC) { 302 LINFO << "Invalid ext4 magic:0x" << std::hex << sb.s_magic << "," << blk_device; 303 *fs_stat |= FS_STAT_EXT4_INVALID_MAGIC; 304 return 0; // not a valid fs, tune2fs, fsck, and mount will all fail. 305 } 306 *fs_stat |= FS_STAT_IS_EXT4; 307 LINFO << "superblock s_max_mnt_count:" << sb.s_max_mnt_count << "," << blk_device; 308 if (sb.s_max_mnt_count == 0xffff) { // -1 (int16) in ext2, but uint16 in ext4 309 *fs_stat |= FS_STAT_NEW_IMAGE_VERSION; 310 } 311 if ((sb.s_feature_incompat & EXT4_FEATURE_INCOMPAT_RECOVER) != 0 || 312 (sb.s_state & EXT4_VALID_FS) == 0) { 313 LINFO << __FUNCTION__ << "(): was not clealy shutdown, state flag:" 314 << std::hex << sb.s_state 315 << "incompat flag:" << std::hex << sb.s_feature_incompat; 316 force_check = 1; 317 *fs_stat |= FS_STAT_UNCLEAN_SHUTDOWN; 318 } 319 int has_quota = (sb.s_feature_ro_compat 320 & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_QUOTA)) != 0; 321 int want_quota = fs_mgr_is_quota(rec) != 0; 322 323 if (has_quota == want_quota) { 324 LINFO << "Requested quota status is match on " << blk_device; 325 return force_check; 326 } else if (want_quota) { 327 LINFO << "Enabling quota on " << blk_device; 328 arg1 = "-Oquota"; 329 arg2 = "-Qusrquota,grpquota"; 330 force_check = 1; 331 *fs_stat |= FS_STAT_QUOTA_ENABLED; 332 } else { 333 LINFO << "Disabling quota on " << blk_device; 334 arg1 = "-Q^usrquota,^grpquota"; 335 arg2 = "-O^quota"; 336 } 337 } else { 338 PERROR << "Failed to open '" << blk_device << "'"; 339 return force_check; 340 } 341 342 const char *tune2fs_argv[] = { 343 TUNE2FS_BIN, 344 arg1, 345 arg2, 346 blk_device, 347 }; 348 ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv), 349 const_cast<char **>(tune2fs_argv), 350 &status, true, LOG_KLOG | LOG_FILE, 351 true, NULL, NULL, 0); 352 if (ret < 0) { 353 /* No need to check for error in fork, we can't really handle it now */ 354 LERROR << "Failed trying to run " << TUNE2FS_BIN; 355 *fs_stat |= FS_STAT_TUNE2FS_FAILED; 356 } 357 } 358 } 359 return force_check; 360 } 361 362 static void do_reserved_size(char *blk_device, char *fs_type, struct fstab_rec *rec, int *fs_stat) 363 { 364 /* Check for the types of filesystems we know how to check */ 365 if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) { 366 /* 367 * Some system images do not have tune2fs for licensing reasons 368 * Detect these and skip reserve blocks. 369 */ 370 if (access(TUNE2FS_BIN, X_OK)) { 371 LERROR << "Not running " << TUNE2FS_BIN << " on " 372 << blk_device << " (executable not in system image)"; 373 } else { 374 LINFO << "Running " << TUNE2FS_BIN << " on " << blk_device; 375 376 int status = 0; 377 int ret = 0; 378 unsigned long reserved_blocks = 0; 379 android::base::unique_fd fd( 380 TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC))); 381 if (fd >= 0) { 382 struct ext4_super_block sb; 383 ret = read_super_block(fd, &sb); 384 if (ret < 0) { 385 PERROR << "Can't read '" << blk_device << "' super block"; 386 return; 387 } 388 reserved_blocks = rec->reserved_size / EXT4_BLOCK_SIZE(&sb); 389 unsigned long reserved_threshold = ext4_blocks_count(&sb) * 0.02; 390 if (reserved_threshold < reserved_blocks) { 391 LWARNING << "Reserved blocks " << reserved_blocks 392 << " is too large"; 393 reserved_blocks = reserved_threshold; 394 } 395 396 if (ext4_r_blocks_count(&sb) == reserved_blocks) { 397 LINFO << "Have reserved same blocks"; 398 return; 399 } 400 } else { 401 PERROR << "Failed to open '" << blk_device << "'"; 402 return; 403 } 404 405 char buf[16] = {0}; 406 snprintf(buf, sizeof (buf), "-r %lu", reserved_blocks); 407 const char *tune2fs_argv[] = { 408 TUNE2FS_BIN, 409 buf, 410 blk_device, 411 }; 412 413 ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv), 414 const_cast<char **>(tune2fs_argv), 415 &status, true, LOG_KLOG | LOG_FILE, 416 true, NULL, NULL, 0); 417 418 if (ret < 0) { 419 /* No need to check for error in fork, we can't really handle it now */ 420 LERROR << "Failed trying to run " << TUNE2FS_BIN; 421 *fs_stat |= FS_STAT_TUNE2FS_FAILED; 422 } 423 } 424 } 425 } 426 427 static void remove_trailing_slashes(char *n) 428 { 429 int len; 430 431 len = strlen(n) - 1; 432 while ((*(n + len) == '/') && len) { 433 *(n + len) = '\0'; 434 len--; 435 } 436 } 437 438 /* 439 * Mark the given block device as read-only, using the BLKROSET ioctl. 440 * Return 0 on success, and -1 on error. 441 */ 442 int fs_mgr_set_blk_ro(const char *blockdev) 443 { 444 int fd; 445 int rc = -1; 446 int ON = 1; 447 448 fd = TEMP_FAILURE_RETRY(open(blockdev, O_RDONLY | O_CLOEXEC)); 449 if (fd < 0) { 450 // should never happen 451 return rc; 452 } 453 454 rc = ioctl(fd, BLKROSET, &ON); 455 close(fd); 456 457 return rc; 458 } 459 460 /* 461 * __mount(): wrapper around the mount() system call which also 462 * sets the underlying block device to read-only if the mount is read-only. 463 * See "man 2 mount" for return values. 464 */ 465 static int __mount(const char *source, const char *target, const struct fstab_rec *rec) 466 { 467 unsigned long mountflags = rec->flags; 468 int ret; 469 int save_errno; 470 471 /* We need this because sometimes we have legacy symlinks 472 * that are lingering around and need cleaning up. 473 */ 474 struct stat info; 475 if (!lstat(target, &info)) 476 if ((info.st_mode & S_IFMT) == S_IFLNK) 477 unlink(target); 478 mkdir(target, 0755); 479 ret = mount(source, target, rec->fs_type, mountflags, rec->fs_options); 480 save_errno = errno; 481 LINFO << __FUNCTION__ << "(source=" << source << ",target=" 482 << target << ",type=" << rec->fs_type << ")=" << ret; 483 if ((ret == 0) && (mountflags & MS_RDONLY) != 0) { 484 fs_mgr_set_blk_ro(source); 485 } 486 errno = save_errno; 487 return ret; 488 } 489 490 static int fs_match(const char *in1, const char *in2) 491 { 492 char *n1; 493 char *n2; 494 int ret; 495 496 n1 = strdup(in1); 497 n2 = strdup(in2); 498 499 remove_trailing_slashes(n1); 500 remove_trailing_slashes(n2); 501 502 ret = !strcmp(n1, n2); 503 504 free(n1); 505 free(n2); 506 507 return ret; 508 } 509 510 static int device_is_force_encrypted() { 511 int ret = -1; 512 char value[PROP_VALUE_MAX]; 513 ret = __system_property_get("ro.vold.forceencryption", value); 514 if (ret < 0) 515 return 0; 516 return strcmp(value, "1") ? 0 : 1; 517 } 518 519 /* 520 * Tries to mount any of the consecutive fstab entries that match 521 * the mountpoint of the one given by fstab->recs[start_idx]. 522 * 523 * end_idx: On return, will be the last rec that was looked at. 524 * attempted_idx: On return, will indicate which fstab rec 525 * succeeded. In case of failure, it will be the start_idx. 526 * Returns 527 * -1 on failure with errno set to match the 1st mount failure. 528 * 0 on success. 529 */ 530 static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_idx, int *attempted_idx) 531 { 532 int i; 533 int mount_errno = 0; 534 int mounted = 0; 535 536 if (!end_idx || !attempted_idx || start_idx >= fstab->num_entries) { 537 errno = EINVAL; 538 if (end_idx) *end_idx = start_idx; 539 if (attempted_idx) *attempted_idx = start_idx; 540 return -1; 541 } 542 543 /* Hunt down an fstab entry for the same mount point that might succeed */ 544 for (i = start_idx; 545 /* We required that fstab entries for the same mountpoint be consecutive */ 546 i < fstab->num_entries && !strcmp(fstab->recs[start_idx].mount_point, fstab->recs[i].mount_point); 547 i++) { 548 /* 549 * Don't try to mount/encrypt the same mount point again. 550 * Deal with alternate entries for the same point which are required to be all following 551 * each other. 552 */ 553 if (mounted) { 554 LERROR << __FUNCTION__ << "(): skipping fstab dup mountpoint=" 555 << fstab->recs[i].mount_point << " rec[" << i 556 << "].fs_type=" << fstab->recs[i].fs_type 557 << " already mounted as " 558 << fstab->recs[*attempted_idx].fs_type; 559 continue; 560 } 561 562 int fs_stat = 0; 563 int force_check = do_quota_with_shutdown_check(fstab->recs[i].blk_device, 564 fstab->recs[i].fs_type, 565 &fstab->recs[i], &fs_stat); 566 if (fs_stat & FS_STAT_EXT4_INVALID_MAGIC) { 567 LERROR << __FUNCTION__ << "(): skipping mount, invalid ext4, mountpoint=" 568 << fstab->recs[i].mount_point << " rec[" << i 569 << "].fs_type=" << fstab->recs[i].fs_type; 570 mount_errno = EINVAL; // continue bootup for FDE 571 continue; 572 } 573 if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) { 574 check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type, 575 fstab->recs[i].mount_point, &fs_stat); 576 } 577 578 if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) { 579 do_reserved_size(fstab->recs[i].blk_device, fstab->recs[i].fs_type, 580 &fstab->recs[i], &fs_stat); 581 } 582 583 int retry_count = 2; 584 while (retry_count-- > 0) { 585 if (!__mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point, 586 &fstab->recs[i])) { 587 *attempted_idx = i; 588 mounted = 1; 589 if (i != start_idx) { 590 LERROR << __FUNCTION__ << "(): Mounted " << fstab->recs[i].blk_device 591 << " on " << fstab->recs[i].mount_point 592 << " with fs_type=" << fstab->recs[i].fs_type << " instead of " 593 << fstab->recs[start_idx].fs_type; 594 } 595 fs_stat &= ~FS_STAT_FULL_MOUNT_FAILED; 596 mount_errno = 0; 597 break; 598 } else { 599 if (retry_count <= 0) break; // run check_fs only once 600 fs_stat |= FS_STAT_FULL_MOUNT_FAILED; 601 /* back up the first errno for crypto decisions */ 602 if (mount_errno == 0) { 603 mount_errno = errno; 604 } 605 // retry after fsck 606 check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type, 607 fstab->recs[i].mount_point, &fs_stat); 608 } 609 } 610 log_fs_stat(fstab->recs[i].blk_device, fs_stat); 611 } 612 613 /* Adjust i for the case where it was still withing the recs[] */ 614 if (i < fstab->num_entries) --i; 615 616 *end_idx = i; 617 if (!mounted) { 618 *attempted_idx = start_idx; 619 errno = mount_errno; 620 return -1; 621 } 622 return 0; 623 } 624 625 static int translate_ext_labels(struct fstab_rec *rec) 626 { 627 DIR *blockdir = NULL; 628 struct dirent *ent; 629 char *label; 630 size_t label_len; 631 int ret = -1; 632 633 if (strncmp(rec->blk_device, "LABEL=", 6)) 634 return 0; 635 636 label = rec->blk_device + 6; 637 label_len = strlen(label); 638 639 if (label_len > 16) { 640 LERROR << "FS label is longer than allowed by filesystem"; 641 goto out; 642 } 643 644 645 blockdir = opendir("/dev/block"); 646 if (!blockdir) { 647 LERROR << "couldn't open /dev/block"; 648 goto out; 649 } 650 651 while ((ent = readdir(blockdir))) { 652 int fd; 653 char super_buf[1024]; 654 struct ext4_super_block *sb; 655 656 if (ent->d_type != DT_BLK) 657 continue; 658 659 fd = openat(dirfd(blockdir), ent->d_name, O_RDONLY); 660 if (fd < 0) { 661 LERROR << "Cannot open block device /dev/block/" << ent->d_name; 662 goto out; 663 } 664 665 if (TEMP_FAILURE_RETRY(lseek(fd, 1024, SEEK_SET)) < 0 || 666 TEMP_FAILURE_RETRY(read(fd, super_buf, 1024)) != 1024) { 667 /* Probably a loopback device or something else without a readable 668 * superblock. 669 */ 670 close(fd); 671 continue; 672 } 673 674 sb = (struct ext4_super_block *)super_buf; 675 if (sb->s_magic != EXT4_SUPER_MAGIC) { 676 LINFO << "/dev/block/" << ent->d_name << " not ext{234}"; 677 continue; 678 } 679 680 if (!strncmp(label, sb->s_volume_name, label_len)) { 681 char *new_blk_device; 682 683 if (asprintf(&new_blk_device, "/dev/block/%s", ent->d_name) < 0) { 684 LERROR << "Could not allocate block device string"; 685 goto out; 686 } 687 688 LINFO << "resolved label " << rec->blk_device << " to " 689 << new_blk_device; 690 691 free(rec->blk_device); 692 rec->blk_device = new_blk_device; 693 ret = 0; 694 break; 695 } 696 } 697 698 out: 699 closedir(blockdir); 700 return ret; 701 } 702 703 static bool needs_block_encryption(const struct fstab_rec* rec) 704 { 705 if (device_is_force_encrypted() && fs_mgr_is_encryptable(rec)) return true; 706 if (rec->fs_mgr_flags & MF_FORCECRYPT) return true; 707 if (rec->fs_mgr_flags & MF_CRYPT) { 708 /* Check for existence of convert_fde breadcrumb file */ 709 char convert_fde_name[PATH_MAX]; 710 snprintf(convert_fde_name, sizeof(convert_fde_name), 711 "%s/misc/vold/convert_fde", rec->mount_point); 712 if (access(convert_fde_name, F_OK) == 0) return true; 713 } 714 if (rec->fs_mgr_flags & MF_FORCEFDEORFBE) { 715 /* Check for absence of convert_fbe breadcrumb file */ 716 char convert_fbe_name[PATH_MAX]; 717 snprintf(convert_fbe_name, sizeof(convert_fbe_name), 718 "%s/convert_fbe", rec->mount_point); 719 if (access(convert_fbe_name, F_OK) != 0) return true; 720 } 721 return false; 722 } 723 724 // Check to see if a mountable volume has encryption requirements 725 static int handle_encryptable(const struct fstab_rec* rec) 726 { 727 /* If this is block encryptable, need to trigger encryption */ 728 if (needs_block_encryption(rec)) { 729 if (umount(rec->mount_point) == 0) { 730 return FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION; 731 } else { 732 PWARNING << "Could not umount " << rec->mount_point 733 << " - allow continue unencrypted"; 734 return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED; 735 } 736 } else if (rec->fs_mgr_flags & (MF_FILEENCRYPTION | MF_FORCEFDEORFBE)) { 737 // Deal with file level encryption 738 LINFO << rec->mount_point << " is file encrypted"; 739 return FS_MGR_MNTALL_DEV_FILE_ENCRYPTED; 740 } else if (fs_mgr_is_encryptable(rec)) { 741 return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED; 742 } else { 743 return FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE; 744 } 745 } 746 747 // TODO: add ueventd notifiers if they don't exist. 748 // This is just doing a wait_for_device for maximum of 1s 749 int fs_mgr_test_access(const char *device) { 750 int tries = 25; 751 while (tries--) { 752 if (!access(device, F_OK) || errno != ENOENT) { 753 return 0; 754 } 755 usleep(40 * 1000); 756 } 757 return -1; 758 } 759 760 bool is_device_secure() { 761 int ret = -1; 762 char value[PROP_VALUE_MAX]; 763 ret = __system_property_get("ro.secure", value); 764 if (ret == 0) { 765 #ifdef ALLOW_SKIP_SECURE_CHECK 766 // Allow eng builds to skip this check if the property 767 // is not readable (happens during early mount) 768 return false; 769 #else 770 // If error and not an 'eng' build, we want to fail secure. 771 return true; 772 #endif 773 } 774 return strcmp(value, "0") ? true : false; 775 } 776 777 /* When multiple fstab records share the same mount_point, it will 778 * try to mount each one in turn, and ignore any duplicates after a 779 * first successful mount. 780 * Returns -1 on error, and FS_MGR_MNTALL_* otherwise. 781 */ 782 int fs_mgr_mount_all(struct fstab *fstab, int mount_mode) 783 { 784 int i = 0; 785 int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE; 786 int error_count = 0; 787 int mret = -1; 788 int mount_errno = 0; 789 int attempted_idx = -1; 790 FsManagerAvbUniquePtr avb_handle(nullptr); 791 792 if (!fstab) { 793 return -1; 794 } 795 796 for (i = 0; i < fstab->num_entries; i++) { 797 /* Don't mount entries that are managed by vold or not for the mount mode*/ 798 if ((fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) || 799 ((mount_mode == MOUNT_MODE_LATE) && !fs_mgr_is_latemount(&fstab->recs[i])) || 800 ((mount_mode == MOUNT_MODE_EARLY) && fs_mgr_is_latemount(&fstab->recs[i]))) { 801 continue; 802 } 803 804 /* Skip swap and raw partition entries such as boot, recovery, etc */ 805 if (!strcmp(fstab->recs[i].fs_type, "swap") || 806 !strcmp(fstab->recs[i].fs_type, "emmc") || 807 !strcmp(fstab->recs[i].fs_type, "mtd")) { 808 continue; 809 } 810 811 /* Skip mounting the root partition, as it will already have been mounted */ 812 if (!strcmp(fstab->recs[i].mount_point, "/")) { 813 if ((fstab->recs[i].fs_mgr_flags & MS_RDONLY) != 0) { 814 fs_mgr_set_blk_ro(fstab->recs[i].blk_device); 815 } 816 continue; 817 } 818 819 /* Translate LABEL= file system labels into block devices */ 820 if (!strcmp(fstab->recs[i].fs_type, "ext2") || 821 !strcmp(fstab->recs[i].fs_type, "ext3") || 822 !strcmp(fstab->recs[i].fs_type, "ext4")) { 823 int tret = translate_ext_labels(&fstab->recs[i]); 824 if (tret < 0) { 825 LERROR << "Could not translate label to block device"; 826 continue; 827 } 828 } 829 830 if (fstab->recs[i].fs_mgr_flags & MF_WAIT) { 831 wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT); 832 } 833 834 if (fstab->recs[i].fs_mgr_flags & MF_AVB) { 835 if (!avb_handle) { 836 avb_handle = FsManagerAvbHandle::Open(*fstab); 837 if (!avb_handle) { 838 LERROR << "Failed to open FsManagerAvbHandle"; 839 return -1; 840 } 841 } 842 if (!avb_handle->SetUpAvb(&fstab->recs[i], true /* wait_for_verity_dev */)) { 843 LERROR << "Failed to set up AVB on partition: " 844 << fstab->recs[i].mount_point << ", skipping!"; 845 /* Skips mounting the device. */ 846 continue; 847 } 848 } else if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && is_device_secure()) { 849 int rc = fs_mgr_setup_verity(&fstab->recs[i], true); 850 if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) { 851 LINFO << "Verity disabled"; 852 } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) { 853 LERROR << "Could not set up verified partition, skipping!"; 854 continue; 855 } 856 } 857 858 int last_idx_inspected; 859 int top_idx = i; 860 861 mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx); 862 i = last_idx_inspected; 863 mount_errno = errno; 864 865 /* Deal with encryptability. */ 866 if (!mret) { 867 int status = handle_encryptable(&fstab->recs[attempted_idx]); 868 869 if (status == FS_MGR_MNTALL_FAIL) { 870 /* Fatal error - no point continuing */ 871 return status; 872 } 873 874 if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) { 875 if (encryptable != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) { 876 // Log and continue 877 LERROR << "Only one encryptable/encrypted partition supported"; 878 } 879 encryptable = status; 880 } 881 882 /* Success! Go get the next one */ 883 continue; 884 } 885 886 /* mount(2) returned an error, handle the encryptable/formattable case */ 887 bool wiped = partition_wiped(fstab->recs[top_idx].blk_device); 888 bool crypt_footer = false; 889 if (mret && mount_errno != EBUSY && mount_errno != EACCES && 890 fs_mgr_is_formattable(&fstab->recs[top_idx]) && wiped) { 891 /* top_idx and attempted_idx point at the same partition, but sometimes 892 * at two different lines in the fstab. Use the top one for formatting 893 * as that is the preferred one. 894 */ 895 LERROR << __FUNCTION__ << "(): " << fstab->recs[top_idx].blk_device 896 << " is wiped and " << fstab->recs[top_idx].mount_point 897 << " " << fstab->recs[top_idx].fs_type 898 << " is formattable. Format it."; 899 if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) && 900 strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) { 901 int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY); 902 if (fd >= 0) { 903 LINFO << __FUNCTION__ << "(): also wipe " 904 << fstab->recs[top_idx].key_loc; 905 wipe_block_device(fd, get_file_size(fd)); 906 close(fd); 907 } else { 908 PERROR << __FUNCTION__ << "(): " 909 << fstab->recs[top_idx].key_loc << " wouldn't open"; 910 } 911 } else if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) && 912 !strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) { 913 crypt_footer = true; 914 } 915 if (fs_mgr_do_format(&fstab->recs[top_idx], crypt_footer) == 0) { 916 /* Let's replay the mount actions. */ 917 i = top_idx - 1; 918 continue; 919 } else { 920 LERROR << __FUNCTION__ << "(): Format failed. " 921 << "Suggest recovery..."; 922 encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY; 923 continue; 924 } 925 } 926 if (mret && mount_errno != EBUSY && mount_errno != EACCES && 927 fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) { 928 if (wiped) { 929 LERROR << __FUNCTION__ << "(): " 930 << fstab->recs[attempted_idx].blk_device 931 << " is wiped and " 932 << fstab->recs[attempted_idx].mount_point << " " 933 << fstab->recs[attempted_idx].fs_type 934 << " is encryptable. Suggest recovery..."; 935 encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY; 936 continue; 937 } else { 938 /* Need to mount a tmpfs at this mountpoint for now, and set 939 * properties that vold will query later for decrypting 940 */ 941 LERROR << __FUNCTION__ << "(): possibly an encryptable blkdev " 942 << fstab->recs[attempted_idx].blk_device 943 << " for mount " << fstab->recs[attempted_idx].mount_point 944 << " type " << fstab->recs[attempted_idx].fs_type; 945 if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) { 946 ++error_count; 947 continue; 948 } 949 } 950 encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED; 951 } else { 952 // fs_options might be null so we cannot use PERROR << directly. 953 // Use StringPrintf to output "(null)" instead. 954 if (fs_mgr_is_nofail(&fstab->recs[attempted_idx])) { 955 PERROR << android::base::StringPrintf( 956 "Ignoring failure to mount an un-encryptable or wiped " 957 "partition on %s at %s options: %s", 958 fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point, 959 fstab->recs[attempted_idx].fs_options); 960 } else { 961 PERROR << android::base::StringPrintf( 962 "Failed to mount an un-encryptable or wiped partition " 963 "on %s at %s options: %s", 964 fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point, 965 fstab->recs[attempted_idx].fs_options); 966 ++error_count; 967 } 968 continue; 969 } 970 } 971 972 if (error_count) { 973 return -1; 974 } else { 975 return encryptable; 976 } 977 } 978 979 /* wrapper to __mount() and expects a fully prepared fstab_rec, 980 * unlike fs_mgr_do_mount which does more things with avb / verity 981 * etc. 982 */ 983 int fs_mgr_do_mount_one(struct fstab_rec *rec) 984 { 985 if (!rec) { 986 return FS_MGR_DOMNT_FAILED; 987 } 988 989 int ret = __mount(rec->blk_device, rec->mount_point, rec); 990 if (ret) { 991 ret = (errno == EBUSY) ? FS_MGR_DOMNT_BUSY : FS_MGR_DOMNT_FAILED; 992 } 993 994 return ret; 995 } 996 997 /* If tmp_mount_point is non-null, mount the filesystem there. This is for the 998 * tmp mount we do to check the user password 999 * If multiple fstab entries are to be mounted on "n_name", it will try to mount each one 1000 * in turn, and stop on 1st success, or no more match. 1001 */ 1002 int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device, 1003 char *tmp_mount_point) 1004 { 1005 int i = 0; 1006 int ret = FS_MGR_DOMNT_FAILED; 1007 int mount_errors = 0; 1008 int first_mount_errno = 0; 1009 char *m; 1010 FsManagerAvbUniquePtr avb_handle(nullptr); 1011 1012 if (!fstab) { 1013 return ret; 1014 } 1015 1016 for (i = 0; i < fstab->num_entries; i++) { 1017 if (!fs_match(fstab->recs[i].mount_point, n_name)) { 1018 continue; 1019 } 1020 1021 /* We found our match */ 1022 /* If this swap or a raw partition, report an error */ 1023 if (!strcmp(fstab->recs[i].fs_type, "swap") || 1024 !strcmp(fstab->recs[i].fs_type, "emmc") || 1025 !strcmp(fstab->recs[i].fs_type, "mtd")) { 1026 LERROR << "Cannot mount filesystem of type " 1027 << fstab->recs[i].fs_type << " on " << n_blk_device; 1028 goto out; 1029 } 1030 1031 /* First check the filesystem if requested */ 1032 if (fstab->recs[i].fs_mgr_flags & MF_WAIT) { 1033 wait_for_file(n_blk_device, WAIT_TIMEOUT); 1034 } 1035 1036 int fs_stat = 0; 1037 int force_check = do_quota_with_shutdown_check(n_blk_device, fstab->recs[i].fs_type, 1038 &fstab->recs[i], &fs_stat); 1039 1040 if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) { 1041 check_fs(n_blk_device, fstab->recs[i].fs_type, 1042 fstab->recs[i].mount_point, &fs_stat); 1043 } 1044 1045 if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) { 1046 do_reserved_size(n_blk_device, fstab->recs[i].fs_type, &fstab->recs[i], &fs_stat); 1047 } 1048 1049 if (fstab->recs[i].fs_mgr_flags & MF_AVB) { 1050 if (!avb_handle) { 1051 avb_handle = FsManagerAvbHandle::Open(*fstab); 1052 if (!avb_handle) { 1053 LERROR << "Failed to open FsManagerAvbHandle"; 1054 return -1; 1055 } 1056 } 1057 if (!avb_handle->SetUpAvb(&fstab->recs[i], true /* wait_for_verity_dev */)) { 1058 LERROR << "Failed to set up AVB on partition: " 1059 << fstab->recs[i].mount_point << ", skipping!"; 1060 /* Skips mounting the device. */ 1061 continue; 1062 } 1063 } else if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && is_device_secure()) { 1064 int rc = fs_mgr_setup_verity(&fstab->recs[i], true); 1065 if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) { 1066 LINFO << "Verity disabled"; 1067 } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) { 1068 LERROR << "Could not set up verified partition, skipping!"; 1069 continue; 1070 } 1071 } 1072 1073 /* Now mount it where requested */ 1074 if (tmp_mount_point) { 1075 m = tmp_mount_point; 1076 } else { 1077 m = fstab->recs[i].mount_point; 1078 } 1079 int retry_count = 2; 1080 while (retry_count-- > 0) { 1081 if (!__mount(n_blk_device, m, &fstab->recs[i])) { 1082 ret = 0; 1083 fs_stat &= ~FS_STAT_FULL_MOUNT_FAILED; 1084 goto out; 1085 } else { 1086 if (retry_count <= 0) break; // run check_fs only once 1087 if (!first_mount_errno) first_mount_errno = errno; 1088 mount_errors++; 1089 fs_stat |= FS_STAT_FULL_MOUNT_FAILED; 1090 // try again after fsck 1091 check_fs(n_blk_device, fstab->recs[i].fs_type, fstab->recs[i].mount_point, &fs_stat); 1092 } 1093 } 1094 log_fs_stat(fstab->recs[i].blk_device, fs_stat); 1095 } 1096 if (mount_errors) { 1097 PERROR << "Cannot mount filesystem on " << n_blk_device 1098 << " at " << m; 1099 if (first_mount_errno == EBUSY) { 1100 ret = FS_MGR_DOMNT_BUSY; 1101 } else { 1102 ret = FS_MGR_DOMNT_FAILED; 1103 } 1104 } else { 1105 /* We didn't find a match, say so and return an error */ 1106 LERROR << "Cannot find mount point " << fstab->recs[i].mount_point 1107 << " in fstab"; 1108 } 1109 1110 out: 1111 return ret; 1112 } 1113 1114 /* 1115 * mount a tmpfs filesystem at the given point. 1116 * return 0 on success, non-zero on failure. 1117 */ 1118 int fs_mgr_do_tmpfs_mount(const char *n_name) 1119 { 1120 int ret; 1121 1122 ret = mount("tmpfs", n_name, "tmpfs", 1123 MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS); 1124 if (ret < 0) { 1125 LERROR << "Cannot mount tmpfs filesystem at " << n_name; 1126 return -1; 1127 } 1128 1129 /* Success */ 1130 return 0; 1131 } 1132 1133 int fs_mgr_unmount_all(struct fstab *fstab) 1134 { 1135 int i = 0; 1136 int ret = 0; 1137 1138 if (!fstab) { 1139 return -1; 1140 } 1141 1142 while (fstab->recs[i].blk_device) { 1143 if (umount(fstab->recs[i].mount_point)) { 1144 LERROR << "Cannot unmount filesystem at " 1145 << fstab->recs[i].mount_point; 1146 ret = -1; 1147 } 1148 i++; 1149 } 1150 1151 return ret; 1152 } 1153 1154 /* This must be called after mount_all, because the mkswap command needs to be 1155 * available. 1156 */ 1157 int fs_mgr_swapon_all(struct fstab *fstab) 1158 { 1159 int i = 0; 1160 int flags = 0; 1161 int err = 0; 1162 int ret = 0; 1163 int status; 1164 const char *mkswap_argv[2] = { 1165 MKSWAP_BIN, 1166 nullptr 1167 }; 1168 1169 if (!fstab) { 1170 return -1; 1171 } 1172 1173 for (i = 0; i < fstab->num_entries; i++) { 1174 /* Skip non-swap entries */ 1175 if (strcmp(fstab->recs[i].fs_type, "swap")) { 1176 continue; 1177 } 1178 1179 if (fstab->recs[i].zram_size > 0) { 1180 /* A zram_size was specified, so we need to configure the 1181 * device. There is no point in having multiple zram devices 1182 * on a system (all the memory comes from the same pool) so 1183 * we can assume the device number is 0. 1184 */ 1185 FILE *zram_fp; 1186 FILE *zram_mcs_fp; 1187 1188 if (fstab->recs[i].max_comp_streams >= 0) { 1189 zram_mcs_fp = fopen(ZRAM_CONF_MCS, "r+"); 1190 if (zram_mcs_fp == NULL) { 1191 LERROR << "Unable to open zram conf comp device " 1192 << ZRAM_CONF_MCS; 1193 ret = -1; 1194 continue; 1195 } 1196 fprintf(zram_mcs_fp, "%d\n", fstab->recs[i].max_comp_streams); 1197 fclose(zram_mcs_fp); 1198 } 1199 1200 zram_fp = fopen(ZRAM_CONF_DEV, "r+"); 1201 if (zram_fp == NULL) { 1202 LERROR << "Unable to open zram conf device " << ZRAM_CONF_DEV; 1203 ret = -1; 1204 continue; 1205 } 1206 fprintf(zram_fp, "%d\n", fstab->recs[i].zram_size); 1207 fclose(zram_fp); 1208 } 1209 1210 if (fstab->recs[i].fs_mgr_flags & MF_WAIT) { 1211 wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT); 1212 } 1213 1214 /* Initialize the swap area */ 1215 mkswap_argv[1] = fstab->recs[i].blk_device; 1216 err = android_fork_execvp_ext(ARRAY_SIZE(mkswap_argv), 1217 const_cast<char **>(mkswap_argv), 1218 &status, true, LOG_KLOG, false, NULL, 1219 NULL, 0); 1220 if (err) { 1221 LERROR << "mkswap failed for " << fstab->recs[i].blk_device; 1222 ret = -1; 1223 continue; 1224 } 1225 1226 /* If -1, then no priority was specified in fstab, so don't set 1227 * SWAP_FLAG_PREFER or encode the priority */ 1228 if (fstab->recs[i].swap_prio >= 0) { 1229 flags = (fstab->recs[i].swap_prio << SWAP_FLAG_PRIO_SHIFT) & 1230 SWAP_FLAG_PRIO_MASK; 1231 flags |= SWAP_FLAG_PREFER; 1232 } else { 1233 flags = 0; 1234 } 1235 err = swapon(fstab->recs[i].blk_device, flags); 1236 if (err) { 1237 LERROR << "swapon failed for " << fstab->recs[i].blk_device; 1238 ret = -1; 1239 } 1240 } 1241 1242 return ret; 1243 } 1244 1245 /* 1246 * key_loc must be at least PROPERTY_VALUE_MAX bytes long 1247 * 1248 * real_blk_device must be at least PROPERTY_VALUE_MAX bytes long 1249 */ 1250 int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc, char *real_blk_device, int size) 1251 { 1252 int i = 0; 1253 1254 if (!fstab) { 1255 return -1; 1256 } 1257 /* Initialize return values to null strings */ 1258 if (key_loc) { 1259 *key_loc = '\0'; 1260 } 1261 if (real_blk_device) { 1262 *real_blk_device = '\0'; 1263 } 1264 1265 /* Look for the encryptable partition to find the data */ 1266 for (i = 0; i < fstab->num_entries; i++) { 1267 /* Don't deal with vold managed enryptable partitions here */ 1268 if (fstab->recs[i].fs_mgr_flags & MF_VOLDMANAGED) { 1269 continue; 1270 } 1271 if (!(fstab->recs[i].fs_mgr_flags 1272 & (MF_CRYPT | MF_FORCECRYPT | MF_FORCEFDEORFBE))) { 1273 continue; 1274 } 1275 1276 /* We found a match */ 1277 if (key_loc) { 1278 strlcpy(key_loc, fstab->recs[i].key_loc, size); 1279 } 1280 if (real_blk_device) { 1281 strlcpy(real_blk_device, fstab->recs[i].blk_device, size); 1282 } 1283 break; 1284 } 1285 1286 return 0; 1287 } 1288 1289 bool fs_mgr_load_verity_state(int* mode) { 1290 /* return the default mode, unless any of the verified partitions are in 1291 * logging mode, in which case return that */ 1292 *mode = VERITY_MODE_DEFAULT; 1293 1294 std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(), 1295 fs_mgr_free_fstab); 1296 if (!fstab) { 1297 LERROR << "Failed to read default fstab"; 1298 return false; 1299 } 1300 1301 for (int i = 0; i < fstab->num_entries; i++) { 1302 if (fs_mgr_is_avb(&fstab->recs[i])) { 1303 *mode = VERITY_MODE_RESTART; // avb only supports restart mode. 1304 break; 1305 } else if (!fs_mgr_is_verified(&fstab->recs[i])) { 1306 continue; 1307 } 1308 1309 int current; 1310 if (load_verity_state(&fstab->recs[i], ¤t) < 0) { 1311 continue; 1312 } 1313 if (current != VERITY_MODE_DEFAULT) { 1314 *mode = current; 1315 break; 1316 } 1317 } 1318 1319 return true; 1320 } 1321 1322 bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback) { 1323 if (!callback) { 1324 return false; 1325 } 1326 1327 int mode; 1328 if (!fs_mgr_load_verity_state(&mode)) { 1329 return false; 1330 } 1331 1332 android::base::unique_fd fd(TEMP_FAILURE_RETRY(open("/dev/device-mapper", O_RDWR | O_CLOEXEC))); 1333 if (fd == -1) { 1334 PERROR << "Error opening device mapper"; 1335 return false; 1336 } 1337 1338 std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(), 1339 fs_mgr_free_fstab); 1340 if (!fstab) { 1341 LERROR << "Failed to read default fstab"; 1342 return false; 1343 } 1344 1345 alignas(dm_ioctl) char buffer[DM_BUF_SIZE]; 1346 struct dm_ioctl* io = (struct dm_ioctl*)buffer; 1347 bool system_root = android::base::GetProperty("ro.build.system_root_image", "") == "true"; 1348 1349 for (int i = 0; i < fstab->num_entries; i++) { 1350 if (!fs_mgr_is_verified(&fstab->recs[i]) && !fs_mgr_is_avb(&fstab->recs[i])) { 1351 continue; 1352 } 1353 1354 std::string mount_point; 1355 if (system_root && !strcmp(fstab->recs[i].mount_point, "/")) { 1356 // In AVB, the dm device name is vroot instead of system. 1357 mount_point = fs_mgr_is_avb(&fstab->recs[i]) ? "vroot" : "system"; 1358 } else { 1359 mount_point = basename(fstab->recs[i].mount_point); 1360 } 1361 1362 fs_mgr_verity_ioctl_init(io, mount_point, 0); 1363 1364 const char* status; 1365 if (ioctl(fd, DM_TABLE_STATUS, io)) { 1366 if (fstab->recs[i].fs_mgr_flags & MF_VERIFYATBOOT) { 1367 status = "V"; 1368 } else { 1369 PERROR << "Failed to query DM_TABLE_STATUS for " << mount_point.c_str(); 1370 continue; 1371 } 1372 } 1373 1374 status = &buffer[io->data_start + sizeof(struct dm_target_spec)]; 1375 1376 // To be consistent in vboot 1.0 and vboot 2.0 (AVB), change the mount_point 1377 // back to 'system' for the callback. So it has property [partition.system.verified] 1378 // instead of [partition.vroot.verified]. 1379 if (mount_point == "vroot") mount_point = "system"; 1380 if (*status == 'C' || *status == 'V') { 1381 callback(&fstab->recs[i], mount_point.c_str(), mode, *status); 1382 } 1383 } 1384 1385 return true; 1386 } 1387