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