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 /* XXX These need to be obtained from kernel headers. See b/9336527 */
     32 #define SWAP_FLAG_PREFER        0x8000
     33 #define SWAP_FLAG_PRIO_MASK     0x7fff
     34 #define SWAP_FLAG_PRIO_SHIFT    0
     35 #define SWAP_FLAG_DISCARD       0x10000
     36 
     37 #include <linux/loop.h>
     38 #include <private/android_filesystem_config.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 "fs_mgr_priv.h"
     48 #include "fs_mgr_priv_verity.h"
     49 
     50 #define KEY_LOC_PROP   "ro.crypto.keyfile.userdata"
     51 #define KEY_IN_FOOTER  "footer"
     52 
     53 #define E2FSCK_BIN      "/system/bin/e2fsck"
     54 #define MKSWAP_BIN      "/system/bin/mkswap"
     55 
     56 #define FSCK_LOG_FILE   "/dev/fscklogs/log"
     57 
     58 #define ZRAM_CONF_DEV   "/sys/block/zram0/disksize"
     59 
     60 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
     61 
     62 struct flag_list {
     63     const char *name;
     64     unsigned flag;
     65 };
     66 
     67 static struct flag_list mount_flags[] = {
     68     { "noatime",    MS_NOATIME },
     69     { "noexec",     MS_NOEXEC },
     70     { "nosuid",     MS_NOSUID },
     71     { "nodev",      MS_NODEV },
     72     { "nodiratime", MS_NODIRATIME },
     73     { "ro",         MS_RDONLY },
     74     { "rw",         0 },
     75     { "remount",    MS_REMOUNT },
     76     { "bind",       MS_BIND },
     77     { "rec",        MS_REC },
     78     { "unbindable", MS_UNBINDABLE },
     79     { "private",    MS_PRIVATE },
     80     { "slave",      MS_SLAVE },
     81     { "shared",     MS_SHARED },
     82     { "defaults",   0 },
     83     { 0,            0 },
     84 };
     85 
     86 static struct flag_list fs_mgr_flags[] = {
     87     { "wait",        MF_WAIT },
     88     { "check",       MF_CHECK },
     89     { "encryptable=",MF_CRYPT },
     90     { "nonremovable",MF_NONREMOVABLE },
     91     { "voldmanaged=",MF_VOLDMANAGED},
     92     { "length=",     MF_LENGTH },
     93     { "recoveryonly",MF_RECOVERYONLY },
     94     { "swapprio=",   MF_SWAPPRIO },
     95     { "zramsize=",   MF_ZRAMSIZE },
     96     { "verify",      MF_VERIFY },
     97     { "noemulatedsd", MF_NOEMULATEDSD },
     98     { "defaults",    0 },
     99     { 0,             0 },
    100 };
    101 
    102 struct fs_mgr_flag_values {
    103     char *key_loc;
    104     long long part_length;
    105     char *label;
    106     int partnum;
    107     int swap_prio;
    108     unsigned int zram_size;
    109 };
    110 
    111 /*
    112  * gettime() - returns the time in seconds of the system's monotonic clock or
    113  * zero on error.
    114  */
    115 static time_t gettime(void)
    116 {
    117     struct timespec ts;
    118     int ret;
    119 
    120     ret = clock_gettime(CLOCK_MONOTONIC, &ts);
    121     if (ret < 0) {
    122         ERROR("clock_gettime(CLOCK_MONOTONIC) failed: %s\n", strerror(errno));
    123         return 0;
    124     }
    125 
    126     return ts.tv_sec;
    127 }
    128 
    129 static int wait_for_file(const char *filename, int timeout)
    130 {
    131     struct stat info;
    132     time_t timeout_time = gettime() + timeout;
    133     int ret = -1;
    134 
    135     while (gettime() < timeout_time && ((ret = stat(filename, &info)) < 0))
    136         usleep(10000);
    137 
    138     return ret;
    139 }
    140 
    141 static int parse_flags(char *flags, struct flag_list *fl,
    142                        struct fs_mgr_flag_values *flag_vals,
    143                        char *fs_options, int fs_options_len)
    144 {
    145     int f = 0;
    146     int i;
    147     char *p;
    148     char *savep;
    149 
    150     /* initialize flag values.  If we find a relevant flag, we'll
    151      * update the value */
    152     if (flag_vals) {
    153         memset(flag_vals, 0, sizeof(*flag_vals));
    154         flag_vals->partnum = -1;
    155         flag_vals->swap_prio = -1; /* negative means it wasn't specified. */
    156     }
    157 
    158     /* initialize fs_options to the null string */
    159     if (fs_options && (fs_options_len > 0)) {
    160         fs_options[0] = '\0';
    161     }
    162 
    163     p = strtok_r(flags, ",", &savep);
    164     while (p) {
    165         /* Look for the flag "p" in the flag list "fl"
    166          * If not found, the loop exits with fl[i].name being null.
    167          */
    168         for (i = 0; fl[i].name; i++) {
    169             if (!strncmp(p, fl[i].name, strlen(fl[i].name))) {
    170                 f |= fl[i].flag;
    171                 if ((fl[i].flag == MF_CRYPT) && flag_vals) {
    172                     /* The encryptable flag is followed by an = and the
    173                      * location of the keys.  Get it and return it.
    174                      */
    175                     flag_vals->key_loc = strdup(strchr(p, '=') + 1);
    176                 } else if ((fl[i].flag == MF_LENGTH) && flag_vals) {
    177                     /* The length flag is followed by an = and the
    178                      * size of the partition.  Get it and return it.
    179                      */
    180                     flag_vals->part_length = strtoll(strchr(p, '=') + 1, NULL, 0);
    181                 } else if ((fl[i].flag == MF_VOLDMANAGED) && flag_vals) {
    182                     /* The voldmanaged flag is followed by an = and the
    183                      * label, a colon and the partition number or the
    184                      * word "auto", e.g.
    185                      *   voldmanaged=sdcard:3
    186                      * Get and return them.
    187                      */
    188                     char *label_start;
    189                     char *label_end;
    190                     char *part_start;
    191 
    192                     label_start = strchr(p, '=') + 1;
    193                     label_end = strchr(p, ':');
    194                     if (label_end) {
    195                         flag_vals->label = strndup(label_start,
    196                                                    (int) (label_end - label_start));
    197                         part_start = strchr(p, ':') + 1;
    198                         if (!strcmp(part_start, "auto")) {
    199                             flag_vals->partnum = -1;
    200                         } else {
    201                             flag_vals->partnum = strtol(part_start, NULL, 0);
    202                         }
    203                     } else {
    204                         ERROR("Warning: voldmanaged= flag malformed\n");
    205                     }
    206                 } else if ((fl[i].flag == MF_SWAPPRIO) && flag_vals) {
    207                     flag_vals->swap_prio = strtoll(strchr(p, '=') + 1, NULL, 0);
    208                 } else if ((fl[i].flag == MF_ZRAMSIZE) && flag_vals) {
    209                     flag_vals->zram_size = strtoll(strchr(p, '=') + 1, NULL, 0);
    210                 }
    211                 break;
    212             }
    213         }
    214 
    215         if (!fl[i].name) {
    216             if (fs_options) {
    217                 /* It's not a known flag, so it must be a filesystem specific
    218                  * option.  Add it to fs_options if it was passed in.
    219                  */
    220                 strlcat(fs_options, p, fs_options_len);
    221                 strlcat(fs_options, ",", fs_options_len);
    222             } else {
    223                 /* fs_options was not passed in, so if the flag is unknown
    224                  * it's an error.
    225                  */
    226                 ERROR("Warning: unknown flag %s\n", p);
    227             }
    228         }
    229         p = strtok_r(NULL, ",", &savep);
    230     }
    231 
    232 out:
    233     if (fs_options && fs_options[0]) {
    234         /* remove the last trailing comma from the list of options */
    235         fs_options[strlen(fs_options) - 1] = '\0';
    236     }
    237 
    238     return f;
    239 }
    240 
    241 /* Read a line of text till the next newline character.
    242  * If no newline is found before the buffer is full, continue reading till a new line is seen,
    243  * then return an empty buffer.  This effectively ignores lines that are too long.
    244  * On EOF, return null.
    245  */
    246 static char *fs_getline(char *buf, int size, FILE *file)
    247 {
    248     int cnt = 0;
    249     int eof = 0;
    250     int eol = 0;
    251     int c;
    252 
    253     if (size < 1) {
    254         return NULL;
    255     }
    256 
    257     while (cnt < (size - 1)) {
    258         c = getc(file);
    259         if (c == EOF) {
    260             eof = 1;
    261             break;
    262         }
    263 
    264         *(buf + cnt) = c;
    265         cnt++;
    266 
    267         if (c == '\n') {
    268             eol = 1;
    269             break;
    270         }
    271     }
    272 
    273     /* Null terminate what we've read */
    274     *(buf + cnt) = '\0';
    275 
    276     if (eof) {
    277         if (cnt) {
    278             return buf;
    279         } else {
    280             return NULL;
    281         }
    282     } else if (eol) {
    283         return buf;
    284     } else {
    285         /* The line is too long.  Read till a newline or EOF.
    286          * If EOF, return null, if newline, return an empty buffer.
    287          */
    288         while(1) {
    289             c = getc(file);
    290             if (c == EOF) {
    291                 return NULL;
    292             } else if (c == '\n') {
    293                 *buf = '\0';
    294                 return buf;
    295             }
    296         }
    297     }
    298 }
    299 
    300 struct fstab *fs_mgr_read_fstab(const char *fstab_path)
    301 {
    302     FILE *fstab_file;
    303     int cnt, entries;
    304     int len;
    305     char line[256];
    306     const char *delim = " \t";
    307     char *save_ptr, *p;
    308     struct fstab *fstab;
    309     struct fstab_rec *recs;
    310     struct fs_mgr_flag_values flag_vals;
    311 #define FS_OPTIONS_LEN 1024
    312     char tmp_fs_options[FS_OPTIONS_LEN];
    313 
    314     fstab_file = fopen(fstab_path, "r");
    315     if (!fstab_file) {
    316         ERROR("Cannot open file %s\n", fstab_path);
    317         return 0;
    318     }
    319 
    320     entries = 0;
    321     while (fs_getline(line, sizeof(line), fstab_file)) {
    322         /* if the last character is a newline, shorten the string by 1 byte */
    323         len = strlen(line);
    324         if (line[len - 1] == '\n') {
    325             line[len - 1] = '\0';
    326         }
    327         /* Skip any leading whitespace */
    328         p = line;
    329         while (isspace(*p)) {
    330             p++;
    331         }
    332         /* ignore comments or empty lines */
    333         if (*p == '#' || *p == '\0')
    334             continue;
    335         entries++;
    336     }
    337 
    338     if (!entries) {
    339         ERROR("No entries found in fstab\n");
    340         return 0;
    341     }
    342 
    343     /* Allocate and init the fstab structure */
    344     fstab = calloc(1, sizeof(struct fstab));
    345     fstab->num_entries = entries;
    346     fstab->fstab_filename = strdup(fstab_path);
    347     fstab->recs = calloc(fstab->num_entries, sizeof(struct fstab_rec));
    348 
    349     fseek(fstab_file, 0, SEEK_SET);
    350 
    351     cnt = 0;
    352     while (fs_getline(line, sizeof(line), fstab_file)) {
    353         /* if the last character is a newline, shorten the string by 1 byte */
    354         len = strlen(line);
    355         if (line[len - 1] == '\n') {
    356             line[len - 1] = '\0';
    357         }
    358 
    359         /* Skip any leading whitespace */
    360         p = line;
    361         while (isspace(*p)) {
    362             p++;
    363         }
    364         /* ignore comments or empty lines */
    365         if (*p == '#' || *p == '\0')
    366             continue;
    367 
    368         /* If a non-comment entry is greater than the size we allocated, give an
    369          * error and quit.  This can happen in the unlikely case the file changes
    370          * between the two reads.
    371          */
    372         if (cnt >= entries) {
    373             ERROR("Tried to process more entries than counted\n");
    374             break;
    375         }
    376 
    377         if (!(p = strtok_r(line, delim, &save_ptr))) {
    378             ERROR("Error parsing mount source\n");
    379             return 0;
    380         }
    381         fstab->recs[cnt].blk_device = strdup(p);
    382 
    383         if (!(p = strtok_r(NULL, delim, &save_ptr))) {
    384             ERROR("Error parsing mount_point\n");
    385             return 0;
    386         }
    387         fstab->recs[cnt].mount_point = strdup(p);
    388 
    389         if (!(p = strtok_r(NULL, delim, &save_ptr))) {
    390             ERROR("Error parsing fs_type\n");
    391             return 0;
    392         }
    393         fstab->recs[cnt].fs_type = strdup(p);
    394 
    395         if (!(p = strtok_r(NULL, delim, &save_ptr))) {
    396             ERROR("Error parsing mount_flags\n");
    397             return 0;
    398         }
    399         tmp_fs_options[0] = '\0';
    400         fstab->recs[cnt].flags = parse_flags(p, mount_flags, NULL,
    401                                        tmp_fs_options, FS_OPTIONS_LEN);
    402 
    403         /* fs_options are optional */
    404         if (tmp_fs_options[0]) {
    405             fstab->recs[cnt].fs_options = strdup(tmp_fs_options);
    406         } else {
    407             fstab->recs[cnt].fs_options = NULL;
    408         }
    409 
    410         if (!(p = strtok_r(NULL, delim, &save_ptr))) {
    411             ERROR("Error parsing fs_mgr_options\n");
    412             return 0;
    413         }
    414         fstab->recs[cnt].fs_mgr_flags = parse_flags(p, fs_mgr_flags,
    415                                                     &flag_vals, NULL, 0);
    416         fstab->recs[cnt].key_loc = flag_vals.key_loc;
    417         fstab->recs[cnt].length = flag_vals.part_length;
    418         fstab->recs[cnt].label = flag_vals.label;
    419         fstab->recs[cnt].partnum = flag_vals.partnum;
    420         fstab->recs[cnt].swap_prio = flag_vals.swap_prio;
    421         fstab->recs[cnt].zram_size = flag_vals.zram_size;
    422         cnt++;
    423     }
    424     fclose(fstab_file);
    425 
    426     return fstab;
    427 }
    428 
    429 void fs_mgr_free_fstab(struct fstab *fstab)
    430 {
    431     int i;
    432 
    433     if (!fstab) {
    434         return;
    435     }
    436 
    437     for (i = 0; i < fstab->num_entries; i++) {
    438         /* Free the pointers return by strdup(3) */
    439         free(fstab->recs[i].blk_device);
    440         free(fstab->recs[i].mount_point);
    441         free(fstab->recs[i].fs_type);
    442         free(fstab->recs[i].fs_options);
    443         free(fstab->recs[i].key_loc);
    444         free(fstab->recs[i].label);
    445         i++;
    446     }
    447 
    448     /* Free the fstab_recs array created by calloc(3) */
    449     free(fstab->recs);
    450 
    451     /* Free the fstab filename */
    452     free(fstab->fstab_filename);
    453 
    454     /* Free fstab */
    455     free(fstab);
    456 }
    457 
    458 static void check_fs(char *blk_device, char *fs_type, char *target)
    459 {
    460     int status;
    461     int ret;
    462     long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID;
    463     char *tmpmnt_opts = "nomblk_io_submit,errors=remount-ro";
    464     char *e2fsck_argv[] = {
    465         E2FSCK_BIN,
    466         "-y",
    467         blk_device
    468     };
    469 
    470     /* Check for the types of filesystems we know how to check */
    471     if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) {
    472         /*
    473          * First try to mount and unmount the filesystem.  We do this because
    474          * the kernel is more efficient than e2fsck in running the journal and
    475          * processing orphaned inodes, and on at least one device with a
    476          * performance issue in the emmc firmware, it can take e2fsck 2.5 minutes
    477          * to do what the kernel does in about a second.
    478          *
    479          * After mounting and unmounting the filesystem, run e2fsck, and if an
    480          * error is recorded in the filesystem superblock, e2fsck will do a full
    481          * check.  Otherwise, it does nothing.  If the kernel cannot mount the
    482          * filesytsem due to an error, e2fsck is still run to do a full check
    483          * fix the filesystem.
    484          */
    485         ret = mount(blk_device, target, fs_type, tmpmnt_flags, tmpmnt_opts);
    486         if (!ret) {
    487             umount(target);
    488         }
    489 
    490         INFO("Running %s on %s\n", E2FSCK_BIN, blk_device);
    491 
    492         ret = android_fork_execvp_ext(ARRAY_SIZE(e2fsck_argv), e2fsck_argv,
    493                                       &status, true, LOG_KLOG | LOG_FILE,
    494                                       true, FSCK_LOG_FILE);
    495 
    496         if (ret < 0) {
    497             /* No need to check for error in fork, we can't really handle it now */
    498             ERROR("Failed trying to run %s\n", E2FSCK_BIN);
    499         }
    500     }
    501 
    502     return;
    503 }
    504 
    505 static void remove_trailing_slashes(char *n)
    506 {
    507     int len;
    508 
    509     len = strlen(n) - 1;
    510     while ((*(n + len) == '/') && len) {
    511       *(n + len) = '\0';
    512       len--;
    513     }
    514 }
    515 
    516 /*
    517  * Mark the given block device as read-only, using the BLKROSET ioctl.
    518  * Return 0 on success, and -1 on error.
    519  */
    520 static void fs_set_blk_ro(const char *blockdev)
    521 {
    522     int fd;
    523     int ON = 1;
    524 
    525     fd = open(blockdev, O_RDONLY);
    526     if (fd < 0) {
    527         // should never happen
    528         return;
    529     }
    530 
    531     ioctl(fd, BLKROSET, &ON);
    532     close(fd);
    533 }
    534 
    535 /*
    536  * __mount(): wrapper around the mount() system call which also
    537  * sets the underlying block device to read-only if the mount is read-only.
    538  * See "man 2 mount" for return values.
    539  */
    540 static int __mount(const char *source, const char *target,
    541                    const char *filesystemtype, unsigned long mountflags,
    542                    const void *data)
    543 {
    544     int ret = mount(source, target, filesystemtype, mountflags, data);
    545 
    546     if ((ret == 0) && (mountflags & MS_RDONLY) != 0) {
    547         fs_set_blk_ro(source);
    548     }
    549 
    550     return ret;
    551 }
    552 
    553 static int fs_match(char *in1, char *in2)
    554 {
    555     char *n1;
    556     char *n2;
    557     int ret;
    558 
    559     n1 = strdup(in1);
    560     n2 = strdup(in2);
    561 
    562     remove_trailing_slashes(n1);
    563     remove_trailing_slashes(n2);
    564 
    565     ret = !strcmp(n1, n2);
    566 
    567     free(n1);
    568     free(n2);
    569 
    570     return ret;
    571 }
    572 
    573 int fs_mgr_mount_all(struct fstab *fstab)
    574 {
    575     int i = 0;
    576     int encrypted = 0;
    577     int ret = -1;
    578     int mret;
    579 
    580     if (!fstab) {
    581         return ret;
    582     }
    583 
    584     for (i = 0; i < fstab->num_entries; i++) {
    585         /* Don't mount entries that are managed by vold */
    586         if (fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) {
    587             continue;
    588         }
    589 
    590         /* Skip swap and raw partition entries such as boot, recovery, etc */
    591         if (!strcmp(fstab->recs[i].fs_type, "swap") ||
    592             !strcmp(fstab->recs[i].fs_type, "emmc") ||
    593             !strcmp(fstab->recs[i].fs_type, "mtd")) {
    594             continue;
    595         }
    596 
    597         if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
    598             wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
    599         }
    600 
    601         if (fstab->recs[i].fs_mgr_flags & MF_CHECK) {
    602             check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
    603                      fstab->recs[i].mount_point);
    604         }
    605 
    606         if (fstab->recs[i].fs_mgr_flags & MF_VERIFY) {
    607             if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) {
    608                 ERROR("Could not set up verified partition, skipping!");
    609                 continue;
    610             }
    611         }
    612 
    613         mret = __mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point,
    614                      fstab->recs[i].fs_type, fstab->recs[i].flags,
    615                      fstab->recs[i].fs_options);
    616 
    617         if (!mret) {
    618             /* Success!  Go get the next one */
    619             continue;
    620         }
    621 
    622         /* mount(2) returned an error, check if it's encrypted and deal with it */
    623         if ((fstab->recs[i].fs_mgr_flags & MF_CRYPT) &&
    624             !partition_wiped(fstab->recs[i].blk_device)) {
    625             /* Need to mount a tmpfs at this mountpoint for now, and set
    626              * properties that vold will query later for decrypting
    627              */
    628             if (mount("tmpfs", fstab->recs[i].mount_point, "tmpfs",
    629                   MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS) < 0) {
    630                 ERROR("Cannot mount tmpfs filesystem for encrypted fs at %s\n",
    631                         fstab->recs[i].mount_point);
    632                 goto out;
    633             }
    634             encrypted = 1;
    635         } else {
    636             ERROR("Cannot mount filesystem on %s at %s\n",
    637                     fstab->recs[i].blk_device, fstab->recs[i].mount_point);
    638             goto out;
    639         }
    640     }
    641 
    642     if (encrypted) {
    643         ret = 1;
    644     } else {
    645         ret = 0;
    646     }
    647 
    648 out:
    649     return ret;
    650 }
    651 
    652 /* If tmp_mount_point is non-null, mount the filesystem there.  This is for the
    653  * tmp mount we do to check the user password
    654  */
    655 int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device,
    656                     char *tmp_mount_point)
    657 {
    658     int i = 0;
    659     int ret = -1;
    660     char *m;
    661 
    662     if (!fstab) {
    663         return ret;
    664     }
    665 
    666     for (i = 0; i < fstab->num_entries; i++) {
    667         if (!fs_match(fstab->recs[i].mount_point, n_name)) {
    668             continue;
    669         }
    670 
    671         /* We found our match */
    672         /* If this swap or a raw partition, report an error */
    673         if (!strcmp(fstab->recs[i].fs_type, "swap") ||
    674             !strcmp(fstab->recs[i].fs_type, "emmc") ||
    675             !strcmp(fstab->recs[i].fs_type, "mtd")) {
    676             ERROR("Cannot mount filesystem of type %s on %s\n",
    677                   fstab->recs[i].fs_type, n_blk_device);
    678             goto out;
    679         }
    680 
    681         /* First check the filesystem if requested */
    682         if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
    683             wait_for_file(n_blk_device, WAIT_TIMEOUT);
    684         }
    685 
    686         if (fstab->recs[i].fs_mgr_flags & MF_CHECK) {
    687             check_fs(n_blk_device, fstab->recs[i].fs_type,
    688                      fstab->recs[i].mount_point);
    689         }
    690 
    691         if (fstab->recs[i].fs_mgr_flags & MF_VERIFY) {
    692             if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) {
    693                 ERROR("Could not set up verified partition, skipping!");
    694                 continue;
    695             }
    696         }
    697 
    698         /* Now mount it where requested */
    699         if (tmp_mount_point) {
    700             m = tmp_mount_point;
    701         } else {
    702             m = fstab->recs[i].mount_point;
    703         }
    704         if (__mount(n_blk_device, m, fstab->recs[i].fs_type,
    705                     fstab->recs[i].flags, fstab->recs[i].fs_options)) {
    706             ERROR("Cannot mount filesystem on %s at %s\n",
    707                     n_blk_device, m);
    708             goto out;
    709         } else {
    710             ret = 0;
    711             goto out;
    712         }
    713     }
    714 
    715     /* We didn't find a match, say so and return an error */
    716     ERROR("Cannot find mount point %s in fstab\n", fstab->recs[i].mount_point);
    717 
    718 out:
    719     return ret;
    720 }
    721 
    722 /*
    723  * mount a tmpfs filesystem at the given point.
    724  * return 0 on success, non-zero on failure.
    725  */
    726 int fs_mgr_do_tmpfs_mount(char *n_name)
    727 {
    728     int ret;
    729 
    730     ret = mount("tmpfs", n_name, "tmpfs",
    731                 MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS);
    732     if (ret < 0) {
    733         ERROR("Cannot mount tmpfs filesystem at %s\n", n_name);
    734         return -1;
    735     }
    736 
    737     /* Success */
    738     return 0;
    739 }
    740 
    741 int fs_mgr_unmount_all(struct fstab *fstab)
    742 {
    743     int i = 0;
    744     int ret = 0;
    745 
    746     if (!fstab) {
    747         return -1;
    748     }
    749 
    750     while (fstab->recs[i].blk_device) {
    751         if (umount(fstab->recs[i].mount_point)) {
    752             ERROR("Cannot unmount filesystem at %s\n", fstab->recs[i].mount_point);
    753             ret = -1;
    754         }
    755         i++;
    756     }
    757 
    758     return ret;
    759 }
    760 
    761 /* This must be called after mount_all, because the mkswap command needs to be
    762  * available.
    763  */
    764 int fs_mgr_swapon_all(struct fstab *fstab)
    765 {
    766     int i = 0;
    767     int flags = 0;
    768     int err = 0;
    769     int ret = 0;
    770     int status;
    771     char *mkswap_argv[2] = {
    772         MKSWAP_BIN,
    773         NULL
    774     };
    775 
    776     if (!fstab) {
    777         return -1;
    778     }
    779 
    780     for (i = 0; i < fstab->num_entries; i++) {
    781         /* Skip non-swap entries */
    782         if (strcmp(fstab->recs[i].fs_type, "swap")) {
    783             continue;
    784         }
    785 
    786         if (fstab->recs[i].zram_size > 0) {
    787             /* A zram_size was specified, so we need to configure the
    788              * device.  There is no point in having multiple zram devices
    789              * on a system (all the memory comes from the same pool) so
    790              * we can assume the device number is 0.
    791              */
    792             FILE *zram_fp;
    793 
    794             zram_fp = fopen(ZRAM_CONF_DEV, "r+");
    795             if (zram_fp == NULL) {
    796                 ERROR("Unable to open zram conf device " ZRAM_CONF_DEV);
    797                 ret = -1;
    798                 continue;
    799             }
    800             fprintf(zram_fp, "%d\n", fstab->recs[i].zram_size);
    801             fclose(zram_fp);
    802         }
    803 
    804         if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
    805             wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
    806         }
    807 
    808         /* Initialize the swap area */
    809         mkswap_argv[1] = fstab->recs[i].blk_device;
    810         err = android_fork_execvp_ext(ARRAY_SIZE(mkswap_argv), mkswap_argv,
    811                                       &status, true, LOG_KLOG, false, NULL);
    812         if (err) {
    813             ERROR("mkswap failed for %s\n", fstab->recs[i].blk_device);
    814             ret = -1;
    815             continue;
    816         }
    817 
    818         /* If -1, then no priority was specified in fstab, so don't set
    819          * SWAP_FLAG_PREFER or encode the priority */
    820         if (fstab->recs[i].swap_prio >= 0) {
    821             flags = (fstab->recs[i].swap_prio << SWAP_FLAG_PRIO_SHIFT) &
    822                     SWAP_FLAG_PRIO_MASK;
    823             flags |= SWAP_FLAG_PREFER;
    824         } else {
    825             flags = 0;
    826         }
    827         err = swapon(fstab->recs[i].blk_device, flags);
    828         if (err) {
    829             ERROR("swapon failed for %s\n", fstab->recs[i].blk_device);
    830             ret = -1;
    831         }
    832     }
    833 
    834     return ret;
    835 }
    836 
    837 /*
    838  * key_loc must be at least PROPERTY_VALUE_MAX bytes long
    839  *
    840  * real_blk_device must be at least PROPERTY_VALUE_MAX bytes long
    841  */
    842 int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc, char *real_blk_device, int size)
    843 {
    844     int i = 0;
    845 
    846     if (!fstab) {
    847         return -1;
    848     }
    849     /* Initialize return values to null strings */
    850     if (key_loc) {
    851         *key_loc = '\0';
    852     }
    853     if (real_blk_device) {
    854         *real_blk_device = '\0';
    855     }
    856 
    857     /* Look for the encryptable partition to find the data */
    858     for (i = 0; i < fstab->num_entries; i++) {
    859         /* Don't deal with vold managed enryptable partitions here */
    860         if (fstab->recs[i].fs_mgr_flags & MF_VOLDMANAGED) {
    861             continue;
    862         }
    863         if (!(fstab->recs[i].fs_mgr_flags & MF_CRYPT)) {
    864             continue;
    865         }
    866 
    867         /* We found a match */
    868         if (key_loc) {
    869             strlcpy(key_loc, fstab->recs[i].key_loc, size);
    870         }
    871         if (real_blk_device) {
    872             strlcpy(real_blk_device, fstab->recs[i].blk_device, size);
    873         }
    874         break;
    875     }
    876 
    877     return 0;
    878 }
    879 
    880 /* Add an entry to the fstab, and return 0 on success or -1 on error */
    881 int fs_mgr_add_entry(struct fstab *fstab,
    882                      const char *mount_point, const char *fs_type,
    883                      const char *blk_device, long long length)
    884 {
    885     struct fstab_rec *new_fstab_recs;
    886     int n = fstab->num_entries;
    887 
    888     new_fstab_recs = (struct fstab_rec *)
    889                      realloc(fstab->recs, sizeof(struct fstab_rec) * (n + 1));
    890 
    891     if (!new_fstab_recs) {
    892         return -1;
    893     }
    894 
    895     /* A new entry was added, so initialize it */
    896      memset(&new_fstab_recs[n], 0, sizeof(struct fstab_rec));
    897      new_fstab_recs[n].mount_point = strdup(mount_point);
    898      new_fstab_recs[n].fs_type = strdup(fs_type);
    899      new_fstab_recs[n].blk_device = strdup(blk_device);
    900      new_fstab_recs[n].length = 0;
    901 
    902      /* Update the fstab struct */
    903      fstab->recs = new_fstab_recs;
    904      fstab->num_entries++;
    905 
    906      return 0;
    907 }
    908 
    909 struct fstab_rec *fs_mgr_get_entry_for_mount_point(struct fstab *fstab, const char *path)
    910 {
    911     int i;
    912 
    913     if (!fstab) {
    914         return NULL;
    915     }
    916 
    917     for (i = 0; i < fstab->num_entries; i++) {
    918         int len = strlen(fstab->recs[i].mount_point);
    919         if (strncmp(path, fstab->recs[i].mount_point, len) == 0 &&
    920             (path[len] == '\0' || path[len] == '/')) {
    921             return &fstab->recs[i];
    922         }
    923     }
    924 
    925     return NULL;
    926 }
    927 
    928 int fs_mgr_is_voldmanaged(struct fstab_rec *fstab)
    929 {
    930     return fstab->fs_mgr_flags & MF_VOLDMANAGED;
    931 }
    932 
    933 int fs_mgr_is_nonremovable(struct fstab_rec *fstab)
    934 {
    935     return fstab->fs_mgr_flags & MF_NONREMOVABLE;
    936 }
    937 
    938 int fs_mgr_is_encryptable(struct fstab_rec *fstab)
    939 {
    940     return fstab->fs_mgr_flags & MF_CRYPT;
    941 }
    942 
    943 int fs_mgr_is_noemulatedsd(struct fstab_rec *fstab)
    944 {
    945     return fstab->fs_mgr_flags & MF_NOEMULATEDSD;
    946 }
    947