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 */
gettime(void)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
wait_for_file(const char * filename,int timeout)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
log_fs_stat(const char * blk_device,int fs_stat)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
should_force_check(int fs_stat)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
check_fs(const char * blk_device,char * fs_type,char * target,int * fs_stat)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 */
read_super_block(int fd,struct ext4_super_block * sb)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
ext4_blocks_count(struct ext4_super_block * es)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
ext4_r_blocks_count(struct ext4_super_block * es)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
do_quota_with_shutdown_check(char * blk_device,char * fs_type,struct fstab_rec * rec,int * fs_stat)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
do_reserved_size(char * blk_device,char * fs_type,struct fstab_rec * rec,int * fs_stat)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
remove_trailing_slashes(char * n)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 */
fs_mgr_set_blk_ro(const char * blockdev)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 */
__mount(const char * source,const char * target,const struct fstab_rec * rec)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
fs_match(const char * in1,const char * in2)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
device_is_force_encrypted()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 */
mount_with_alternatives(struct fstab * fstab,int start_idx,int * end_idx,int * attempted_idx)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
translate_ext_labels(struct fstab_rec * rec)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
needs_block_encryption(const struct fstab_rec * rec)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
handle_encryptable(const struct fstab_rec * rec)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
fs_mgr_test_access(const char * device)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
is_device_secure()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 */
fs_mgr_mount_all(struct fstab * fstab,int mount_mode)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 */
fs_mgr_do_mount_one(struct fstab_rec * rec)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 */
fs_mgr_do_mount(struct fstab * fstab,const char * n_name,char * n_blk_device,char * tmp_mount_point)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 */
fs_mgr_do_tmpfs_mount(const char * n_name)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
fs_mgr_unmount_all(struct fstab * fstab)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 */
fs_mgr_swapon_all(struct fstab * fstab)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 */
fs_mgr_get_crypt_info(struct fstab * fstab,char * key_loc,char * real_blk_device,int size)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
fs_mgr_load_verity_state(int * mode)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
fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback)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