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)
    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 */
    507         if (fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) {
    508             continue;
    509         }
    510 
    511         /* Skip swap and raw partition entries such as boot, recovery, etc */
    512         if (!strcmp(fstab->recs[i].fs_type, "swap") ||
    513             !strcmp(fstab->recs[i].fs_type, "emmc") ||
    514             !strcmp(fstab->recs[i].fs_type, "mtd")) {
    515             continue;
    516         }
    517 
    518         /* Skip mounting the root partition, as it will already have been mounted */
    519         if (!strcmp(fstab->recs[i].mount_point, "/")) {
    520             if ((fstab->recs[i].fs_mgr_flags & MS_RDONLY) != 0) {
    521                 fs_mgr_set_blk_ro(fstab->recs[i].blk_device);
    522             }
    523             continue;
    524         }
    525 
    526         /* Translate LABEL= file system labels into block devices */
    527         if (!strcmp(fstab->recs[i].fs_type, "ext2") ||
    528             !strcmp(fstab->recs[i].fs_type, "ext3") ||
    529             !strcmp(fstab->recs[i].fs_type, "ext4")) {
    530             int tret = translate_ext_labels(&fstab->recs[i]);
    531             if (tret < 0) {
    532                 ERROR("Could not translate label to block device\n");
    533                 continue;
    534             }
    535         }
    536 
    537         if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
    538             wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
    539         }
    540 
    541         if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
    542             int rc = fs_mgr_setup_verity(&fstab->recs[i]);
    543             if (device_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
    544                 INFO("Verity disabled");
    545             } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
    546                 ERROR("Could not set up verified partition, skipping!\n");
    547                 continue;
    548             }
    549         }
    550         int last_idx_inspected;
    551         int top_idx = i;
    552 
    553         mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx);
    554         i = last_idx_inspected;
    555         mount_errno = errno;
    556 
    557         /* Deal with encryptability. */
    558         if (!mret) {
    559             int status = handle_encryptable(&fstab->recs[attempted_idx]);
    560 
    561             if (status == FS_MGR_MNTALL_FAIL) {
    562                 /* Fatal error - no point continuing */
    563                 return status;
    564             }
    565 
    566             if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
    567                 if (encryptable != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
    568                     // Log and continue
    569                     ERROR("Only one encryptable/encrypted partition supported\n");
    570                 }
    571                 encryptable = status;
    572             }
    573 
    574             /* Success!  Go get the next one */
    575             continue;
    576         }
    577 
    578         /* mount(2) returned an error, handle the encryptable/formattable case */
    579         bool wiped = partition_wiped(fstab->recs[top_idx].blk_device);
    580         if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
    581             fs_mgr_is_formattable(&fstab->recs[top_idx]) && wiped) {
    582             /* top_idx and attempted_idx point at the same partition, but sometimes
    583              * at two different lines in the fstab.  Use the top one for formatting
    584              * as that is the preferred one.
    585              */
    586             ERROR("%s(): %s is wiped and %s %s is formattable. Format it.\n", __func__,
    587                   fstab->recs[top_idx].blk_device, fstab->recs[top_idx].mount_point,
    588                   fstab->recs[top_idx].fs_type);
    589             if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
    590                 strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
    591                 int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY, 0644);
    592                 if (fd >= 0) {
    593                     INFO("%s(): also wipe %s\n", __func__, fstab->recs[top_idx].key_loc);
    594                     wipe_block_device(fd, get_file_size(fd));
    595                     close(fd);
    596                 } else {
    597                     ERROR("%s(): %s wouldn't open (%s)\n", __func__,
    598                           fstab->recs[top_idx].key_loc, strerror(errno));
    599                 }
    600             }
    601             if (fs_mgr_do_format(&fstab->recs[top_idx]) == 0) {
    602                 /* Let's replay the mount actions. */
    603                 i = top_idx - 1;
    604                 continue;
    605             } else {
    606                 ERROR("%s(): Format failed. Suggest recovery...\n", __func__);
    607                 encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
    608                 continue;
    609             }
    610         }
    611         if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
    612             fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
    613             if (wiped) {
    614                 ERROR("%s(): %s is wiped and %s %s is encryptable. Suggest recovery...\n", __func__,
    615                       fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
    616                       fstab->recs[attempted_idx].fs_type);
    617                 encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
    618                 continue;
    619             } else {
    620                 /* Need to mount a tmpfs at this mountpoint for now, and set
    621                  * properties that vold will query later for decrypting
    622                  */
    623                 ERROR("%s(): possibly an encryptable blkdev %s for mount %s type %s )\n", __func__,
    624                       fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
    625                       fstab->recs[attempted_idx].fs_type);
    626                 if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) {
    627                     ++error_count;
    628                     continue;
    629                 }
    630             }
    631             encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
    632         } else {
    633             if (fs_mgr_is_nofail(&fstab->recs[attempted_idx])) {
    634                 ERROR("Ignoring failure to mount an un-encryptable or wiped partition on"
    635                        "%s at %s options: %s error: %s\n",
    636                        fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
    637                        fstab->recs[attempted_idx].fs_options, strerror(mount_errno));
    638             } else {
    639                 ERROR("Failed to mount an un-encryptable or wiped partition on"
    640                        "%s at %s options: %s error: %s\n",
    641                        fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
    642                        fstab->recs[attempted_idx].fs_options, strerror(mount_errno));
    643                 ++error_count;
    644             }
    645             continue;
    646         }
    647     }
    648 
    649     if (error_count) {
    650         return -1;
    651     } else {
    652         return encryptable;
    653     }
    654 }
    655 
    656 /* If tmp_mount_point is non-null, mount the filesystem there.  This is for the
    657  * tmp mount we do to check the user password
    658  * If multiple fstab entries are to be mounted on "n_name", it will try to mount each one
    659  * in turn, and stop on 1st success, or no more match.
    660  */
    661 int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device,
    662                     char *tmp_mount_point)
    663 {
    664     int i = 0;
    665     int ret = FS_MGR_DOMNT_FAILED;
    666     int mount_errors = 0;
    667     int first_mount_errno = 0;
    668     char *m;
    669 
    670     if (!fstab) {
    671         return ret;
    672     }
    673 
    674     for (i = 0; i < fstab->num_entries; i++) {
    675         if (!fs_match(fstab->recs[i].mount_point, n_name)) {
    676             continue;
    677         }
    678 
    679         /* We found our match */
    680         /* If this swap or a raw partition, report an error */
    681         if (!strcmp(fstab->recs[i].fs_type, "swap") ||
    682             !strcmp(fstab->recs[i].fs_type, "emmc") ||
    683             !strcmp(fstab->recs[i].fs_type, "mtd")) {
    684             ERROR("Cannot mount filesystem of type %s on %s\n",
    685                   fstab->recs[i].fs_type, n_blk_device);
    686             goto out;
    687         }
    688 
    689         /* First check the filesystem if requested */
    690         if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
    691             wait_for_file(n_blk_device, WAIT_TIMEOUT);
    692         }
    693 
    694         if (fstab->recs[i].fs_mgr_flags & MF_CHECK) {
    695             check_fs(n_blk_device, fstab->recs[i].fs_type,
    696                      fstab->recs[i].mount_point);
    697         }
    698 
    699         if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
    700             int rc = fs_mgr_setup_verity(&fstab->recs[i]);
    701             if (device_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
    702                 INFO("Verity disabled");
    703             } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
    704                 ERROR("Could not set up verified partition, skipping!\n");
    705                 continue;
    706             }
    707         }
    708 
    709         /* Now mount it where requested */
    710         if (tmp_mount_point) {
    711             m = tmp_mount_point;
    712         } else {
    713             m = fstab->recs[i].mount_point;
    714         }
    715         if (__mount(n_blk_device, m, &fstab->recs[i])) {
    716             if (!first_mount_errno) first_mount_errno = errno;
    717             mount_errors++;
    718             continue;
    719         } else {
    720             ret = 0;
    721             goto out;
    722         }
    723     }
    724     if (mount_errors) {
    725         ERROR("Cannot mount filesystem on %s at %s. error: %s\n",
    726             n_blk_device, m, strerror(first_mount_errno));
    727         if (first_mount_errno == EBUSY) {
    728             ret = FS_MGR_DOMNT_BUSY;
    729         } else {
    730             ret = FS_MGR_DOMNT_FAILED;
    731         }
    732     } else {
    733         /* We didn't find a match, say so and return an error */
    734         ERROR("Cannot find mount point %s in fstab\n", fstab->recs[i].mount_point);
    735     }
    736 
    737 out:
    738     return ret;
    739 }
    740 
    741 /*
    742  * mount a tmpfs filesystem at the given point.
    743  * return 0 on success, non-zero on failure.
    744  */
    745 int fs_mgr_do_tmpfs_mount(char *n_name)
    746 {
    747     int ret;
    748 
    749     ret = mount("tmpfs", n_name, "tmpfs",
    750                 MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS);
    751     if (ret < 0) {
    752         ERROR("Cannot mount tmpfs filesystem at %s\n", n_name);
    753         return -1;
    754     }
    755 
    756     /* Success */
    757     return 0;
    758 }
    759 
    760 int fs_mgr_unmount_all(struct fstab *fstab)
    761 {
    762     int i = 0;
    763     int ret = 0;
    764 
    765     if (!fstab) {
    766         return -1;
    767     }
    768 
    769     while (fstab->recs[i].blk_device) {
    770         if (umount(fstab->recs[i].mount_point)) {
    771             ERROR("Cannot unmount filesystem at %s\n", fstab->recs[i].mount_point);
    772             ret = -1;
    773         }
    774         i++;
    775     }
    776 
    777     return ret;
    778 }
    779 
    780 /* This must be called after mount_all, because the mkswap command needs to be
    781  * available.
    782  */
    783 int fs_mgr_swapon_all(struct fstab *fstab)
    784 {
    785     int i = 0;
    786     int flags = 0;
    787     int err = 0;
    788     int ret = 0;
    789     int status;
    790     char *mkswap_argv[2] = {
    791         MKSWAP_BIN,
    792         NULL
    793     };
    794 
    795     if (!fstab) {
    796         return -1;
    797     }
    798 
    799     for (i = 0; i < fstab->num_entries; i++) {
    800         /* Skip non-swap entries */
    801         if (strcmp(fstab->recs[i].fs_type, "swap")) {
    802             continue;
    803         }
    804 
    805         if (fstab->recs[i].zram_size > 0) {
    806             /* A zram_size was specified, so we need to configure the
    807              * device.  There is no point in having multiple zram devices
    808              * on a system (all the memory comes from the same pool) so
    809              * we can assume the device number is 0.
    810              */
    811             FILE *zram_fp;
    812 
    813             zram_fp = fopen(ZRAM_CONF_DEV, "r+");
    814             if (zram_fp == NULL) {
    815                 ERROR("Unable to open zram conf device %s\n", ZRAM_CONF_DEV);
    816                 ret = -1;
    817                 continue;
    818             }
    819             fprintf(zram_fp, "%d\n", fstab->recs[i].zram_size);
    820             fclose(zram_fp);
    821         }
    822 
    823         if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
    824             wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
    825         }
    826 
    827         /* Initialize the swap area */
    828         mkswap_argv[1] = fstab->recs[i].blk_device;
    829         err = android_fork_execvp_ext(ARRAY_SIZE(mkswap_argv), mkswap_argv,
    830                                       &status, true, LOG_KLOG, false, NULL,
    831                                       NULL, 0);
    832         if (err) {
    833             ERROR("mkswap failed for %s\n", fstab->recs[i].blk_device);
    834             ret = -1;
    835             continue;
    836         }
    837 
    838         /* If -1, then no priority was specified in fstab, so don't set
    839          * SWAP_FLAG_PREFER or encode the priority */
    840         if (fstab->recs[i].swap_prio >= 0) {
    841             flags = (fstab->recs[i].swap_prio << SWAP_FLAG_PRIO_SHIFT) &
    842                     SWAP_FLAG_PRIO_MASK;
    843             flags |= SWAP_FLAG_PREFER;
    844         } else {
    845             flags = 0;
    846         }
    847         err = swapon(fstab->recs[i].blk_device, flags);
    848         if (err) {
    849             ERROR("swapon failed for %s\n", fstab->recs[i].blk_device);
    850             ret = -1;
    851         }
    852     }
    853 
    854     return ret;
    855 }
    856 
    857 /*
    858  * key_loc must be at least PROPERTY_VALUE_MAX bytes long
    859  *
    860  * real_blk_device must be at least PROPERTY_VALUE_MAX bytes long
    861  */
    862 int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc, char *real_blk_device, int size)
    863 {
    864     int i = 0;
    865 
    866     if (!fstab) {
    867         return -1;
    868     }
    869     /* Initialize return values to null strings */
    870     if (key_loc) {
    871         *key_loc = '\0';
    872     }
    873     if (real_blk_device) {
    874         *real_blk_device = '\0';
    875     }
    876 
    877     /* Look for the encryptable partition to find the data */
    878     for (i = 0; i < fstab->num_entries; i++) {
    879         /* Don't deal with vold managed enryptable partitions here */
    880         if (fstab->recs[i].fs_mgr_flags & MF_VOLDMANAGED) {
    881             continue;
    882         }
    883         if (!(fstab->recs[i].fs_mgr_flags
    884               & (MF_CRYPT | MF_FORCECRYPT | MF_FORCEFDEORFBE))) {
    885             continue;
    886         }
    887 
    888         /* We found a match */
    889         if (key_loc) {
    890             strlcpy(key_loc, fstab->recs[i].key_loc, size);
    891         }
    892         if (real_blk_device) {
    893             strlcpy(real_blk_device, fstab->recs[i].blk_device, size);
    894         }
    895         break;
    896     }
    897 
    898     return 0;
    899 }
    900