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