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