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