Home | History | Annotate | Download | only in fs_mgr
      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 <stdio.h>
     18 #include <stdlib.h>
     19 #include <string.h>
     20 #include <unistd.h>
     21 #include <fcntl.h>
     22 #include <ctype.h>
     23 #include <sys/mount.h>
     24 #include <sys/stat.h>
     25 #include <errno.h>
     26 #include <sys/types.h>
     27 #include <sys/wait.h>
     28 #include <libgen.h>
     29 #include <time.h>
     30 #include <sys/swap.h>
     31 #include <dirent.h>
     32 #include <ext4.h>
     33 #include <ext4_sb.h>
     34 #include <ext4_crypt_init_extensions.h>
     35 
     36 #include <linux/loop.h>
     37 #include <private/android_filesystem_config.h>
     38 #include <cutils/android_reboot.h>
     39 #include <cutils/partition_utils.h>
     40 #include <cutils/properties.h>
     41 #include <logwrap/logwrap.h>
     42 
     43 #include "mincrypt/rsa.h"
     44 #include "mincrypt/sha.h"
     45 #include "mincrypt/sha256.h"
     46 
     47 #include "ext4_utils.h"
     48 #include "wipe.h"
     49 
     50 #include "fs_mgr_priv.h"
     51 #include "fs_mgr_priv_verity.h"
     52 
     53 #define KEY_LOC_PROP   "ro.crypto.keyfile.userdata"
     54 #define KEY_IN_FOOTER  "footer"
     55 
     56 #define E2FSCK_BIN      "/system/bin/e2fsck"
     57 #define F2FS_FSCK_BIN  "/system/bin/fsck.f2fs"
     58 #define MKSWAP_BIN      "/system/bin/mkswap"
     59 
     60 #define FSCK_LOG_FILE   "/dev/fscklogs/log"
     61 
     62 #define ZRAM_CONF_DEV   "/sys/block/zram0/disksize"
     63 
     64 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
     65 
     66 /*
     67  * gettime() - returns the time in seconds of the system's monotonic clock or
     68  * zero on error.
     69  */
     70 static time_t gettime(void)
     71 {
     72     struct timespec ts;
     73     int ret;
     74 
     75     ret = clock_gettime(CLOCK_MONOTONIC, &ts);
     76     if (ret < 0) {
     77         ERROR("clock_gettime(CLOCK_MONOTONIC) failed: %s\n", strerror(errno));
     78         return 0;
     79     }
     80 
     81     return ts.tv_sec;
     82 }
     83 
     84 static int wait_for_file(const char *filename, int timeout)
     85 {
     86     struct stat info;
     87     time_t timeout_time = gettime() + timeout;
     88     int ret = -1;
     89 
     90     while (gettime() < timeout_time && ((ret = stat(filename, &info)) < 0))
     91         usleep(10000);
     92 
     93     return ret;
     94 }
     95 
     96 static void check_fs(char *blk_device, char *fs_type, char *target)
     97 {
     98     int status;
     99     int ret;
    100     long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID;
    101     char tmpmnt_opts[64] = "errors=remount-ro";
    102     char *e2fsck_argv[] = {
    103         E2FSCK_BIN,
    104         "-f",
    105         "-y",
    106         blk_device
    107     };
    108 
    109     /* Check for the types of filesystems we know how to check */
    110     if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) {
    111         /*
    112          * First try to mount and unmount the filesystem.  We do this because
    113          * the kernel is more efficient than e2fsck in running the journal and
    114          * processing orphaned inodes, and on at least one device with a
    115          * performance issue in the emmc firmware, it can take e2fsck 2.5 minutes
    116          * to do what the kernel does in about a second.
    117          *
    118          * After mounting and unmounting the filesystem, run e2fsck, and if an
    119          * error is recorded in the filesystem superblock, e2fsck will do a full
    120          * check.  Otherwise, it does nothing.  If the kernel cannot mount the
    121          * filesytsem due to an error, e2fsck is still run to do a full check
    122          * fix the filesystem.
    123          */
    124         errno = 0;
    125         if (!strcmp(fs_type, "ext4")) {
    126             // This option is only valid with ext4
    127             strlcat(tmpmnt_opts, ",nomblk_io_submit", sizeof(tmpmnt_opts));
    128         }
    129         ret = mount(blk_device, target, fs_type, tmpmnt_flags, tmpmnt_opts);
    130         INFO("%s(): mount(%s,%s,%s)=%d: %s\n",
    131              __func__, blk_device, target, fs_type, ret, strerror(errno));
    132         if (!ret) {
    133             int i;
    134             for (i = 0; i < 5; i++) {
    135                 // Try to umount 5 times before continuing on.
    136                 // Should we try rebooting if all attempts fail?
    137                 int result = umount(target);
    138                 if (result == 0) {
    139                     INFO("%s(): unmount(%s) succeeded\n", __func__, target);
    140                     break;
    141                 }
    142                 ERROR("%s(): umount(%s)=%d: %s\n", __func__, target, result, strerror(errno));
    143                 sleep(1);
    144             }
    145         }
    146 
    147         /*
    148          * Some system images do not have e2fsck for licensing reasons
    149          * (e.g. recent SDK system images). Detect these and skip the check.
    150          */
    151         if (access(E2FSCK_BIN, X_OK)) {
    152             INFO("Not running %s on %s (executable not in system image)\n",
    153                  E2FSCK_BIN, blk_device);
    154         } else {
    155             INFO("Running %s on %s\n", E2FSCK_BIN, blk_device);
    156 
    157             ret = android_fork_execvp_ext(ARRAY_SIZE(e2fsck_argv), e2fsck_argv,
    158                                           &status, true, LOG_KLOG | LOG_FILE,
    159                                           true, FSCK_LOG_FILE, NULL, 0);
    160 
    161             if (ret < 0) {
    162                 /* No need to check for error in fork, we can't really handle it now */
    163                 ERROR("Failed trying to run %s\n", E2FSCK_BIN);
    164             }
    165         }
    166     } else if (!strcmp(fs_type, "f2fs")) {
    167             char *f2fs_fsck_argv[] = {
    168                     F2FS_FSCK_BIN,
    169                     "-a",
    170                     blk_device
    171             };
    172         INFO("Running %s -a %s\n", F2FS_FSCK_BIN, blk_device);
    173 
    174         ret = android_fork_execvp_ext(ARRAY_SIZE(f2fs_fsck_argv), f2fs_fsck_argv,
    175                                       &status, true, LOG_KLOG | LOG_FILE,
    176                                       true, FSCK_LOG_FILE, NULL, 0);
    177         if (ret < 0) {
    178             /* No need to check for error in fork, we can't really handle it now */
    179             ERROR("Failed trying to run %s\n", F2FS_FSCK_BIN);
    180         }
    181     }
    182 
    183     return;
    184 }
    185 
    186 static void remove_trailing_slashes(char *n)
    187 {
    188     int len;
    189 
    190     len = strlen(n) - 1;
    191     while ((*(n + len) == '/') && len) {
    192       *(n + len) = '\0';
    193       len--;
    194     }
    195 }
    196 
    197 /*
    198  * Mark the given block device as read-only, using the BLKROSET ioctl.
    199  * Return 0 on success, and -1 on error.
    200  */
    201 int fs_mgr_set_blk_ro(const char *blockdev)
    202 {
    203     int fd;
    204     int rc = -1;
    205     int ON = 1;
    206 
    207     fd = TEMP_FAILURE_RETRY(open(blockdev, O_RDONLY | O_CLOEXEC));
    208     if (fd < 0) {
    209         // should never happen
    210         return rc;
    211     }
    212 
    213     rc = ioctl(fd, BLKROSET, &ON);
    214     close(fd);
    215 
    216     return rc;
    217 }
    218 
    219 /*
    220  * __mount(): wrapper around the mount() system call which also
    221  * sets the underlying block device to read-only if the mount is read-only.
    222  * See "man 2 mount" for return values.
    223  */
    224 static int __mount(const char *source, const char *target, const struct fstab_rec *rec)
    225 {
    226     unsigned long mountflags = rec->flags;
    227     int ret;
    228     int save_errno;
    229 
    230     /* We need this because sometimes we have legacy symlinks
    231      * that are lingering around and need cleaning up.
    232      */
    233     struct stat info;
    234     if (!lstat(target, &info))
    235         if ((info.st_mode & S_IFMT) == S_IFLNK)
    236             unlink(target);
    237     mkdir(target, 0755);
    238     ret = mount(source, target, rec->fs_type, mountflags, rec->fs_options);
    239     save_errno = errno;
    240     INFO("%s(source=%s,target=%s,type=%s)=%d\n", __func__, source, target, rec->fs_type, ret);
    241     if ((ret == 0) && (mountflags & MS_RDONLY) != 0) {
    242         fs_mgr_set_blk_ro(source);
    243     }
    244     errno = save_errno;
    245     return ret;
    246 }
    247 
    248 static int fs_match(char *in1, char *in2)
    249 {
    250     char *n1;
    251     char *n2;
    252     int ret;
    253 
    254     n1 = strdup(in1);
    255     n2 = strdup(in2);
    256 
    257     remove_trailing_slashes(n1);
    258     remove_trailing_slashes(n2);
    259 
    260     ret = !strcmp(n1, n2);
    261 
    262     free(n1);
    263     free(n2);
    264 
    265     return ret;
    266 }
    267 
    268 static int device_is_debuggable() {
    269     int ret = -1;
    270     char value[PROP_VALUE_MAX];
    271     ret = __system_property_get("ro.debuggable", value);
    272     if (ret < 0)
    273         return ret;
    274     return strcmp(value, "1") ? 0 : 1;
    275 }
    276 
    277 static int device_is_secure() {
    278     int ret = -1;
    279     char value[PROP_VALUE_MAX];
    280     ret = __system_property_get("ro.secure", value);
    281     /* If error, we want to fail secure */
    282     if (ret < 0)
    283         return 1;
    284     return strcmp(value, "0") ? 1 : 0;
    285 }
    286 
    287 static int device_is_force_encrypted() {
    288     int ret = -1;
    289     char value[PROP_VALUE_MAX];
    290     ret = __system_property_get("ro.vold.forceencryption", value);
    291     if (ret < 0)
    292         return 0;
    293     return strcmp(value, "1") ? 0 : 1;
    294 }
    295 
    296 /*
    297  * Tries to mount any of the consecutive fstab entries that match
    298  * the mountpoint of the one given by fstab->recs[start_idx].
    299  *
    300  * end_idx: On return, will be the last rec that was looked at.
    301  * attempted_idx: On return, will indicate which fstab rec
    302  *     succeeded. In case of failure, it will be the start_idx.
    303  * Returns
    304  *   -1 on failure with errno set to match the 1st mount failure.
    305  *   0 on success.
    306  */
    307 static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_idx, int *attempted_idx)
    308 {
    309     int i;
    310     int mount_errno = 0;
    311     int mounted = 0;
    312 
    313     if (!end_idx || !attempted_idx || start_idx >= fstab->num_entries) {
    314       errno = EINVAL;
    315       if (end_idx) *end_idx = start_idx;
    316       if (attempted_idx) *end_idx = start_idx;
    317       return -1;
    318     }
    319 
    320     /* Hunt down an fstab entry for the same mount point that might succeed */
    321     for (i = start_idx;
    322          /* We required that fstab entries for the same mountpoint be consecutive */
    323          i < fstab->num_entries && !strcmp(fstab->recs[start_idx].mount_point, fstab->recs[i].mount_point);
    324          i++) {
    325             /*
    326              * Don't try to mount/encrypt the same mount point again.
    327              * Deal with alternate entries for the same point which are required to be all following
    328              * each other.
    329              */
    330             if (mounted) {
    331                 ERROR("%s(): skipping fstab dup mountpoint=%s rec[%d].fs_type=%s already mounted as %s.\n", __func__,
    332                      fstab->recs[i].mount_point, i, fstab->recs[i].fs_type, fstab->recs[*attempted_idx].fs_type);
    333                 continue;
    334             }
    335 
    336             if (fstab->recs[i].fs_mgr_flags & MF_CHECK) {
    337                 check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
    338                          fstab->recs[i].mount_point);
    339             }
    340             if (!__mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point, &fstab->recs[i])) {
    341                 *attempted_idx = i;
    342                 mounted = 1;
    343                 if (i != start_idx) {
    344                     ERROR("%s(): Mounted %s on %s with fs_type=%s instead of %s\n", __func__,
    345                          fstab->recs[i].blk_device, fstab->recs[i].mount_point, fstab->recs[i].fs_type,
    346                          fstab->recs[start_idx].fs_type);
    347                 }
    348             } else {
    349                 /* back up errno for crypto decisions */
    350                 mount_errno = errno;
    351             }
    352     }
    353 
    354     /* Adjust i for the case where it was still withing the recs[] */
    355     if (i < fstab->num_entries) --i;
    356 
    357     *end_idx = i;
    358     if (!mounted) {
    359         *attempted_idx = start_idx;
    360         errno = mount_errno;
    361         return -1;
    362     }
    363     return 0;
    364 }
    365 
    366 static int translate_ext_labels(struct fstab_rec *rec)
    367 {
    368     DIR *blockdir = NULL;
    369     struct dirent *ent;
    370     char *label;
    371     size_t label_len;
    372     int ret = -1;
    373 
    374     if (strncmp(rec->blk_device, "LABEL=", 6))
    375         return 0;
    376 
    377     label = rec->blk_device + 6;
    378     label_len = strlen(label);
    379 
    380     if (label_len > 16) {
    381         ERROR("FS label is longer than allowed by filesystem\n");
    382         goto out;
    383     }
    384 
    385 
    386     blockdir = opendir("/dev/block");
    387     if (!blockdir) {
    388         ERROR("couldn't open /dev/block\n");
    389         goto out;
    390     }
    391 
    392     while ((ent = readdir(blockdir))) {
    393         int fd;
    394         char super_buf[1024];
    395         struct ext4_super_block *sb;
    396 
    397         if (ent->d_type != DT_BLK)
    398             continue;
    399 
    400         fd = openat(dirfd(blockdir), ent->d_name, O_RDONLY);
    401         if (fd < 0) {
    402             ERROR("Cannot open block device /dev/block/%s\n", ent->d_name);
    403             goto out;
    404         }
    405 
    406         if (TEMP_FAILURE_RETRY(lseek(fd, 1024, SEEK_SET)) < 0 ||
    407             TEMP_FAILURE_RETRY(read(fd, super_buf, 1024)) != 1024) {
    408             /* Probably a loopback device or something else without a readable
    409              * superblock.
    410              */
    411             close(fd);
    412             continue;
    413         }
    414 
    415         sb = (struct ext4_super_block *)super_buf;
    416         if (sb->s_magic != EXT4_SUPER_MAGIC) {
    417             INFO("/dev/block/%s not ext{234}\n", ent->d_name);
    418             continue;
    419         }
    420 
    421         if (!strncmp(label, sb->s_volume_name, label_len)) {
    422             char *new_blk_device;
    423 
    424             if (asprintf(&new_blk_device, "/dev/block/%s", ent->d_name) < 0) {
    425                 ERROR("Could not allocate block device string\n");
    426                 goto out;
    427             }
    428 
    429             INFO("resolved label %s to %s\n", rec->blk_device, new_blk_device);
    430 
    431             free(rec->blk_device);
    432             rec->blk_device = new_blk_device;
    433             ret = 0;
    434             break;
    435         }
    436     }
    437 
    438 out:
    439     closedir(blockdir);
    440     return ret;
    441 }
    442 
    443 static bool needs_block_encryption(const struct fstab_rec* rec)
    444 {
    445     if (device_is_force_encrypted() && fs_mgr_is_encryptable(rec)) return true;
    446     if (rec->fs_mgr_flags & MF_FORCECRYPT) return true;
    447     if (rec->fs_mgr_flags & MF_CRYPT) {
    448         /* Check for existence of convert_fde breadcrumb file */
    449         char convert_fde_name[PATH_MAX];
    450         snprintf(convert_fde_name, sizeof(convert_fde_name),
    451                  "%s/misc/vold/convert_fde", rec->mount_point);
    452         if (access(convert_fde_name, F_OK) == 0) return true;
    453     }
    454     if (rec->fs_mgr_flags & MF_FORCEFDEORFBE) {
    455         /* Check for absence of convert_fbe breadcrumb file */
    456         char convert_fbe_name[PATH_MAX];
    457         snprintf(convert_fbe_name, sizeof(convert_fbe_name),
    458                  "%s/convert_fbe", rec->mount_point);
    459         if (access(convert_fbe_name, F_OK) != 0) return true;
    460     }
    461     return false;
    462 }
    463 
    464 // Check to see if a mountable volume has encryption requirements
    465 static int handle_encryptable(const struct fstab_rec* rec)
    466 {
    467     /* If this is block encryptable, need to trigger encryption */
    468     if (needs_block_encryption(rec)) {
    469         if (umount(rec->mount_point) == 0) {
    470             return FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION;
    471         } else {
    472             WARNING("Could not umount %s (%s) - allow continue unencrypted\n",
    473                     rec->mount_point, strerror(errno));
    474             return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED;
    475         }
    476     } else if (rec->fs_mgr_flags & (MF_FILEENCRYPTION | MF_FORCEFDEORFBE)) {
    477     // Deal with file level encryption
    478         INFO("%s is file encrypted\n", rec->mount_point);
    479         return FS_MGR_MNTALL_DEV_FILE_ENCRYPTED;
    480     } else if (fs_mgr_is_encryptable(rec)) {
    481         return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED;
    482     } else {
    483         return FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE;
    484     }
    485 }
    486 
    487 /* When multiple fstab records share the same mount_point, it will
    488  * try to mount each one in turn, and ignore any duplicates after a
    489  * first successful mount.
    490  * Returns -1 on error, and  FS_MGR_MNTALL_* otherwise.
    491  */
    492 int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
    493 {
    494     int i = 0;
    495     int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE;
    496     int error_count = 0;
    497     int mret = -1;
    498     int mount_errno = 0;
    499     int attempted_idx = -1;
    500 
    501     if (!fstab) {
    502         return -1;
    503     }
    504 
    505     for (i = 0; i < fstab->num_entries; i++) {
    506         /* Don't mount entries that are managed by vold or not for the mount mode*/
    507         if ((fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) ||
    508              ((mount_mode == MOUNT_MODE_LATE) && !fs_mgr_is_latemount(&fstab->recs[i])) ||
    509              ((mount_mode == MOUNT_MODE_EARLY) && fs_mgr_is_latemount(&fstab->recs[i]))) {
    510             continue;
    511         }
    512 
    513         /* Skip swap and raw partition entries such as boot, recovery, etc */
    514         if (!strcmp(fstab->recs[i].fs_type, "swap") ||
    515             !strcmp(fstab->recs[i].fs_type, "emmc") ||
    516             !strcmp(fstab->recs[i].fs_type, "mtd")) {
    517             continue;
    518         }
    519 
    520         /* Skip mounting the root partition, as it will already have been mounted */
    521         if (!strcmp(fstab->recs[i].mount_point, "/")) {
    522             if ((fstab->recs[i].fs_mgr_flags & MS_RDONLY) != 0) {
    523                 fs_mgr_set_blk_ro(fstab->recs[i].blk_device);
    524             }
    525             continue;
    526         }
    527 
    528         /* Translate LABEL= file system labels into block devices */
    529         if (!strcmp(fstab->recs[i].fs_type, "ext2") ||
    530             !strcmp(fstab->recs[i].fs_type, "ext3") ||
    531             !strcmp(fstab->recs[i].fs_type, "ext4")) {
    532             int tret = translate_ext_labels(&fstab->recs[i]);
    533             if (tret < 0) {
    534                 ERROR("Could not translate label to block device\n");
    535                 continue;
    536             }
    537         }
    538 
    539         if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
    540             wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
    541         }
    542 
    543         if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
    544             int rc = fs_mgr_setup_verity(&fstab->recs[i]);
    545             if (device_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
    546                 INFO("Verity disabled");
    547             } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
    548                 ERROR("Could not set up verified partition, skipping!\n");
    549                 continue;
    550             }
    551         }
    552         int last_idx_inspected;
    553         int top_idx = i;
    554 
    555         mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx);
    556         i = last_idx_inspected;
    557         mount_errno = errno;
    558 
    559         /* Deal with encryptability. */
    560         if (!mret) {
    561             int status = handle_encryptable(&fstab->recs[attempted_idx]);
    562 
    563             if (status == FS_MGR_MNTALL_FAIL) {
    564                 /* Fatal error - no point continuing */
    565                 return status;
    566             }
    567 
    568             if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
    569                 if (encryptable != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
    570                     // Log and continue
    571                     ERROR("Only one encryptable/encrypted partition supported\n");
    572                 }
    573                 encryptable = status;
    574             }
    575 
    576             /* Success!  Go get the next one */
    577             continue;
    578         }
    579 
    580         /* mount(2) returned an error, handle the encryptable/formattable case */
    581         bool wiped = partition_wiped(fstab->recs[top_idx].blk_device);
    582         if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
    583             fs_mgr_is_formattable(&fstab->recs[top_idx]) && wiped) {
    584             /* top_idx and attempted_idx point at the same partition, but sometimes
    585              * at two different lines in the fstab.  Use the top one for formatting
    586              * as that is the preferred one.
    587              */
    588             ERROR("%s(): %s is wiped and %s %s is formattable. Format it.\n", __func__,
    589                   fstab->recs[top_idx].blk_device, fstab->recs[top_idx].mount_point,
    590                   fstab->recs[top_idx].fs_type);
    591             if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
    592                 strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
    593                 int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY, 0644);
    594                 if (fd >= 0) {
    595                     INFO("%s(): also wipe %s\n", __func__, fstab->recs[top_idx].key_loc);
    596                     wipe_block_device(fd, get_file_size(fd));
    597                     close(fd);
    598                 } else {
    599                     ERROR("%s(): %s wouldn't open (%s)\n", __func__,
    600                           fstab->recs[top_idx].key_loc, strerror(errno));
    601                 }
    602             }
    603             if (fs_mgr_do_format(&fstab->recs[top_idx]) == 0) {
    604                 /* Let's replay the mount actions. */
    605                 i = top_idx - 1;
    606                 continue;
    607             } else {
    608                 ERROR("%s(): Format failed. Suggest recovery...\n", __func__);
    609                 encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
    610                 continue;
    611             }
    612         }
    613         if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
    614             fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
    615             if (wiped) {
    616                 ERROR("%s(): %s is wiped and %s %s is encryptable. Suggest recovery...\n", __func__,
    617                       fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
    618                       fstab->recs[attempted_idx].fs_type);
    619                 encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
    620                 continue;
    621             } else {
    622                 /* Need to mount a tmpfs at this mountpoint for now, and set
    623                  * properties that vold will query later for decrypting
    624                  */
    625                 ERROR("%s(): possibly an encryptable blkdev %s for mount %s type %s )\n", __func__,
    626                       fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
    627                       fstab->recs[attempted_idx].fs_type);
    628                 if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) {
    629                     ++error_count;
    630                     continue;
    631                 }
    632             }
    633             encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
    634         } else {
    635             if (fs_mgr_is_nofail(&fstab->recs[attempted_idx])) {
    636                 ERROR("Ignoring failure to mount an un-encryptable or wiped partition on"
    637                        "%s at %s options: %s error: %s\n",
    638                        fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
    639                        fstab->recs[attempted_idx].fs_options, strerror(mount_errno));
    640             } else {
    641                 ERROR("Failed to mount an un-encryptable or wiped partition on"
    642                        "%s at %s options: %s error: %s\n",
    643                        fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
    644                        fstab->recs[attempted_idx].fs_options, strerror(mount_errno));
    645                 ++error_count;
    646             }
    647             continue;
    648         }
    649     }
    650 
    651     if (error_count) {
    652         return -1;
    653     } else {
    654         return encryptable;
    655     }
    656 }
    657 
    658 /* If tmp_mount_point is non-null, mount the filesystem there.  This is for the
    659  * tmp mount we do to check the user password
    660  * If multiple fstab entries are to be mounted on "n_name", it will try to mount each one
    661  * in turn, and stop on 1st success, or no more match.
    662  */
    663 int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device,
    664                     char *tmp_mount_point)
    665 {
    666     int i = 0;
    667     int ret = FS_MGR_DOMNT_FAILED;
    668     int mount_errors = 0;
    669     int first_mount_errno = 0;
    670     char *m;
    671 
    672     if (!fstab) {
    673         return ret;
    674     }
    675 
    676     for (i = 0; i < fstab->num_entries; i++) {
    677         if (!fs_match(fstab->recs[i].mount_point, n_name)) {
    678             continue;
    679         }
    680 
    681         /* We found our match */
    682         /* If this swap or a raw partition, report an error */
    683         if (!strcmp(fstab->recs[i].fs_type, "swap") ||
    684             !strcmp(fstab->recs[i].fs_type, "emmc") ||
    685             !strcmp(fstab->recs[i].fs_type, "mtd")) {
    686             ERROR("Cannot mount filesystem of type %s on %s\n",
    687                   fstab->recs[i].fs_type, n_blk_device);
    688             goto out;
    689         }
    690 
    691         /* First check the filesystem if requested */
    692         if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
    693             wait_for_file(n_blk_device, WAIT_TIMEOUT);
    694         }
    695 
    696         if (fstab->recs[i].fs_mgr_flags & MF_CHECK) {
    697             check_fs(n_blk_device, fstab->recs[i].fs_type,
    698                      fstab->recs[i].mount_point);
    699         }
    700 
    701         if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
    702             int rc = fs_mgr_setup_verity(&fstab->recs[i]);
    703             if (device_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
    704                 INFO("Verity disabled");
    705             } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
    706                 ERROR("Could not set up verified partition, skipping!\n");
    707                 continue;
    708             }
    709         }
    710 
    711         /* Now mount it where requested */
    712         if (tmp_mount_point) {
    713             m = tmp_mount_point;
    714         } else {
    715             m = fstab->recs[i].mount_point;
    716         }
    717         if (__mount(n_blk_device, m, &fstab->recs[i])) {
    718             if (!first_mount_errno) first_mount_errno = errno;
    719             mount_errors++;
    720             continue;
    721         } else {
    722             ret = 0;
    723             goto out;
    724         }
    725     }
    726     if (mount_errors) {
    727         ERROR("Cannot mount filesystem on %s at %s. error: %s\n",
    728             n_blk_device, m, strerror(first_mount_errno));
    729         if (first_mount_errno == EBUSY) {
    730             ret = FS_MGR_DOMNT_BUSY;
    731         } else {
    732             ret = FS_MGR_DOMNT_FAILED;
    733         }
    734     } else {
    735         /* We didn't find a match, say so and return an error */
    736         ERROR("Cannot find mount point %s in fstab\n", fstab->recs[i].mount_point);
    737     }
    738 
    739 out:
    740     return ret;
    741 }
    742 
    743 /*
    744  * mount a tmpfs filesystem at the given point.
    745  * return 0 on success, non-zero on failure.
    746  */
    747 int fs_mgr_do_tmpfs_mount(char *n_name)
    748 {
    749     int ret;
    750 
    751     ret = mount("tmpfs", n_name, "tmpfs",
    752                 MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS);
    753     if (ret < 0) {
    754         ERROR("Cannot mount tmpfs filesystem at %s\n", n_name);
    755         return -1;
    756     }
    757 
    758     /* Success */
    759     return 0;
    760 }
    761 
    762 int fs_mgr_unmount_all(struct fstab *fstab)
    763 {
    764     int i = 0;
    765     int ret = 0;
    766 
    767     if (!fstab) {
    768         return -1;
    769     }
    770 
    771     while (fstab->recs[i].blk_device) {
    772         if (umount(fstab->recs[i].mount_point)) {
    773             ERROR("Cannot unmount filesystem at %s\n", fstab->recs[i].mount_point);
    774             ret = -1;
    775         }
    776         i++;
    777     }
    778 
    779     return ret;
    780 }
    781 
    782 /* This must be called after mount_all, because the mkswap command needs to be
    783  * available.
    784  */
    785 int fs_mgr_swapon_all(struct fstab *fstab)
    786 {
    787     int i = 0;
    788     int flags = 0;
    789     int err = 0;
    790     int ret = 0;
    791     int status;
    792     char *mkswap_argv[2] = {
    793         MKSWAP_BIN,
    794         NULL
    795     };
    796 
    797     if (!fstab) {
    798         return -1;
    799     }
    800 
    801     for (i = 0; i < fstab->num_entries; i++) {
    802         /* Skip non-swap entries */
    803         if (strcmp(fstab->recs[i].fs_type, "swap")) {
    804             continue;
    805         }
    806 
    807         if (fstab->recs[i].zram_size > 0) {
    808             /* A zram_size was specified, so we need to configure the
    809              * device.  There is no point in having multiple zram devices
    810              * on a system (all the memory comes from the same pool) so
    811              * we can assume the device number is 0.
    812              */
    813             FILE *zram_fp;
    814 
    815             zram_fp = fopen(ZRAM_CONF_DEV, "r+");
    816             if (zram_fp == NULL) {
    817                 ERROR("Unable to open zram conf device %s\n", ZRAM_CONF_DEV);
    818                 ret = -1;
    819                 continue;
    820             }
    821             fprintf(zram_fp, "%d\n", fstab->recs[i].zram_size);
    822             fclose(zram_fp);
    823         }
    824 
    825         if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
    826             wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
    827         }
    828 
    829         /* Initialize the swap area */
    830         mkswap_argv[1] = fstab->recs[i].blk_device;
    831         err = android_fork_execvp_ext(ARRAY_SIZE(mkswap_argv), mkswap_argv,
    832                                       &status, true, LOG_KLOG, false, NULL,
    833                                       NULL, 0);
    834         if (err) {
    835             ERROR("mkswap failed for %s\n", fstab->recs[i].blk_device);
    836             ret = -1;
    837             continue;
    838         }
    839 
    840         /* If -1, then no priority was specified in fstab, so don't set
    841          * SWAP_FLAG_PREFER or encode the priority */
    842         if (fstab->recs[i].swap_prio >= 0) {
    843             flags = (fstab->recs[i].swap_prio << SWAP_FLAG_PRIO_SHIFT) &
    844                     SWAP_FLAG_PRIO_MASK;
    845             flags |= SWAP_FLAG_PREFER;
    846         } else {
    847             flags = 0;
    848         }
    849         err = swapon(fstab->recs[i].blk_device, flags);
    850         if (err) {
    851             ERROR("swapon failed for %s\n", fstab->recs[i].blk_device);
    852             ret = -1;
    853         }
    854     }
    855 
    856     return ret;
    857 }
    858 
    859 /*
    860  * key_loc must be at least PROPERTY_VALUE_MAX bytes long
    861  *
    862  * real_blk_device must be at least PROPERTY_VALUE_MAX bytes long
    863  */
    864 int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc, char *real_blk_device, int size)
    865 {
    866     int i = 0;
    867 
    868     if (!fstab) {
    869         return -1;
    870     }
    871     /* Initialize return values to null strings */
    872     if (key_loc) {
    873         *key_loc = '\0';
    874     }
    875     if (real_blk_device) {
    876         *real_blk_device = '\0';
    877     }
    878 
    879     /* Look for the encryptable partition to find the data */
    880     for (i = 0; i < fstab->num_entries; i++) {
    881         /* Don't deal with vold managed enryptable partitions here */
    882         if (fstab->recs[i].fs_mgr_flags & MF_VOLDMANAGED) {
    883             continue;
    884         }
    885         if (!(fstab->recs[i].fs_mgr_flags
    886               & (MF_CRYPT | MF_FORCECRYPT | MF_FORCEFDEORFBE))) {
    887             continue;
    888         }
    889 
    890         /* We found a match */
    891         if (key_loc) {
    892             strlcpy(key_loc, fstab->recs[i].key_loc, size);
    893         }
    894         if (real_blk_device) {
    895             strlcpy(real_blk_device, fstab->recs[i].blk_device, size);
    896         }
    897         break;
    898     }
    899 
    900     return 0;
    901 }
    902