• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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], &current) < 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