fs_mgr.c revision cee206880ef80ac570df6b369d12f111c00f653a
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
32#include <linux/loop.h>
33#include <private/android_filesystem_config.h>
34#include <cutils/android_reboot.h>
35#include <cutils/partition_utils.h>
36#include <cutils/properties.h>
37#include <logwrap/logwrap.h>
38
39#include "mincrypt/rsa.h"
40#include "mincrypt/sha.h"
41#include "mincrypt/sha256.h"
42
43#include "fs_mgr_priv.h"
44#include "fs_mgr_priv_verity.h"
45
46#define KEY_LOC_PROP   "ro.crypto.keyfile.userdata"
47#define KEY_IN_FOOTER  "footer"
48
49#define E2FSCK_BIN      "/system/bin/e2fsck"
50#define F2FS_FSCK_BIN  "/system/bin/fsck.f2fs"
51#define MKSWAP_BIN      "/system/bin/mkswap"
52
53#define FSCK_LOG_FILE   "/dev/fscklogs/log"
54
55#define ZRAM_CONF_DEV   "/sys/block/zram0/disksize"
56
57#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
58
59/*
60 * gettime() - returns the time in seconds of the system's monotonic clock or
61 * zero on error.
62 */
63static time_t gettime(void)
64{
65    struct timespec ts;
66    int ret;
67
68    ret = clock_gettime(CLOCK_MONOTONIC, &ts);
69    if (ret < 0) {
70        ERROR("clock_gettime(CLOCK_MONOTONIC) failed: %s\n", strerror(errno));
71        return 0;
72    }
73
74    return ts.tv_sec;
75}
76
77static int wait_for_file(const char *filename, int timeout)
78{
79    struct stat info;
80    time_t timeout_time = gettime() + timeout;
81    int ret = -1;
82
83    while (gettime() < timeout_time && ((ret = stat(filename, &info)) < 0))
84        usleep(10000);
85
86    return ret;
87}
88
89static void check_fs(char *blk_device, char *fs_type, char *target)
90{
91    int status;
92    int ret;
93    long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID;
94    char *tmpmnt_opts = "nomblk_io_submit,errors=remount-ro";
95    char *e2fsck_argv[] = {
96        E2FSCK_BIN,
97        "-y",
98        blk_device
99    };
100
101    /* Check for the types of filesystems we know how to check */
102    if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) {
103        /*
104         * First try to mount and unmount the filesystem.  We do this because
105         * the kernel is more efficient than e2fsck in running the journal and
106         * processing orphaned inodes, and on at least one device with a
107         * performance issue in the emmc firmware, it can take e2fsck 2.5 minutes
108         * to do what the kernel does in about a second.
109         *
110         * After mounting and unmounting the filesystem, run e2fsck, and if an
111         * error is recorded in the filesystem superblock, e2fsck will do a full
112         * check.  Otherwise, it does nothing.  If the kernel cannot mount the
113         * filesytsem due to an error, e2fsck is still run to do a full check
114         * fix the filesystem.
115         */
116        ret = mount(blk_device, target, fs_type, tmpmnt_flags, tmpmnt_opts);
117        INFO("%s(): mount(%s,%s,%s)=%d\n", __func__, blk_device, target, fs_type, ret);
118        if (!ret) {
119            umount(target);
120        }
121
122        /*
123         * Some system images do not have e2fsck for licensing reasons
124         * (e.g. recent SDK system images). Detect these and skip the check.
125         */
126        if (access(E2FSCK_BIN, X_OK)) {
127            INFO("Not running %s on %s (executable not in system image)\n",
128                 E2FSCK_BIN, blk_device);
129        } else {
130            INFO("Running %s on %s\n", E2FSCK_BIN, blk_device);
131
132            ret = android_fork_execvp_ext(ARRAY_SIZE(e2fsck_argv), e2fsck_argv,
133                                        &status, true, LOG_KLOG | LOG_FILE,
134                                        true, FSCK_LOG_FILE);
135
136            if (ret < 0) {
137                /* No need to check for error in fork, we can't really handle it now */
138                ERROR("Failed trying to run %s\n", E2FSCK_BIN);
139            }
140        }
141    } else if (!strcmp(fs_type, "f2fs")) {
142            char *f2fs_fsck_argv[] = {
143                    F2FS_FSCK_BIN,
144                    blk_device
145            };
146        INFO("Running %s on %s\n", F2FS_FSCK_BIN, blk_device);
147
148        ret = android_fork_execvp_ext(ARRAY_SIZE(f2fs_fsck_argv), f2fs_fsck_argv,
149                                      &status, true, LOG_KLOG | LOG_FILE,
150                                      true, FSCK_LOG_FILE);
151        if (ret < 0) {
152            /* No need to check for error in fork, we can't really handle it now */
153            ERROR("Failed trying to run %s\n", F2FS_FSCK_BIN);
154        }
155    }
156
157    return;
158}
159
160static void remove_trailing_slashes(char *n)
161{
162    int len;
163
164    len = strlen(n) - 1;
165    while ((*(n + len) == '/') && len) {
166      *(n + len) = '\0';
167      len--;
168    }
169}
170
171/*
172 * Mark the given block device as read-only, using the BLKROSET ioctl.
173 * Return 0 on success, and -1 on error.
174 */
175static void fs_set_blk_ro(const char *blockdev)
176{
177    int fd;
178    int ON = 1;
179
180    fd = open(blockdev, O_RDONLY);
181    if (fd < 0) {
182        // should never happen
183        return;
184    }
185
186    ioctl(fd, BLKROSET, &ON);
187    close(fd);
188}
189
190/*
191 * __mount(): wrapper around the mount() system call which also
192 * sets the underlying block device to read-only if the mount is read-only.
193 * See "man 2 mount" for return values.
194 */
195static int __mount(const char *source, const char *target, const struct fstab_rec *rec)
196{
197    unsigned long mountflags = rec->flags;
198    int ret;
199    int save_errno;
200
201    /* We need this because sometimes we have legacy symlinks
202     * that are lingering around and need cleaning up.
203     */
204    struct stat info;
205    if (!lstat(target, &info))
206        if ((info.st_mode & S_IFMT) == S_IFLNK)
207            unlink(target);
208    mkdir(target, 0755);
209    ret = mount(source, target, rec->fs_type, mountflags, rec->fs_options);
210    save_errno = errno;
211    INFO("%s(source=%s,target=%s,type=%s)=%d\n", __func__, source, target, rec->fs_type, ret);
212    if ((ret == 0) && (mountflags & MS_RDONLY) != 0) {
213        fs_set_blk_ro(source);
214    }
215    errno = save_errno;
216    return ret;
217}
218
219static int fs_match(char *in1, char *in2)
220{
221    char *n1;
222    char *n2;
223    int ret;
224
225    n1 = strdup(in1);
226    n2 = strdup(in2);
227
228    remove_trailing_slashes(n1);
229    remove_trailing_slashes(n2);
230
231    ret = !strcmp(n1, n2);
232
233    free(n1);
234    free(n2);
235
236    return ret;
237}
238
239static int device_is_debuggable() {
240    int ret = -1;
241    char value[PROP_VALUE_MAX];
242    ret = __system_property_get("ro.debuggable", value);
243    if (ret < 0)
244        return ret;
245    return strcmp(value, "1") ? 0 : 1;
246}
247
248/*
249 * Tries to mount any of the consecutive fstab entries that match
250 * the mountpoint of the one given by fstab->recs[start_idx].
251 *
252 * end_idx: On return, will be the last rec that was looked at.
253 * attempted_idx: On return, will indicate which fstab rec
254 *     succeeded. In case of failure, it will be the start_idx.
255 * Returns
256 *   -1 on failure with errno set to match the 1st mount failure.
257 *   0 on success.
258 */
259static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_idx, int *attempted_idx)
260{
261    int i;
262    int mount_errno = 0;
263    int mounted = 0;
264
265    if (!end_idx || !attempted_idx || start_idx >= fstab->num_entries) {
266      errno = EINVAL;
267      if (end_idx) *end_idx = start_idx;
268      if (attempted_idx) *end_idx = start_idx;
269      return -1;
270    }
271
272    /* Hunt down an fstab entry for the same mount point that might succeed */
273    for (i = start_idx;
274         /* We required that fstab entries for the same mountpoint be consecutive */
275         i < fstab->num_entries && !strcmp(fstab->recs[start_idx].mount_point, fstab->recs[i].mount_point);
276         i++) {
277            /*
278             * Don't try to mount/encrypt the same mount point again.
279             * Deal with alternate entries for the same point which are required to be all following
280             * each other.
281             */
282            if (mounted) {
283                ERROR("%s(): skipping fstab dup mountpoint=%s rec[%d].fs_type=%s already mounted as %s.\n", __func__,
284                     fstab->recs[i].mount_point, i, fstab->recs[i].fs_type, fstab->recs[*attempted_idx].fs_type);
285                continue;
286            }
287
288            if (fstab->recs[i].fs_mgr_flags & MF_CHECK) {
289                check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
290                         fstab->recs[i].mount_point);
291            }
292            if (!__mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point, &fstab->recs[i])) {
293                *attempted_idx = i;
294                mounted = 1;
295                if (i != start_idx) {
296                    ERROR("%s(): Mounted %s on %s with fs_type=%s instead of %s\n", __func__,
297                         fstab->recs[i].blk_device, fstab->recs[i].mount_point, fstab->recs[i].fs_type,
298                         fstab->recs[start_idx].fs_type);
299                }
300            } else {
301                /* back up errno for crypto decisions */
302                mount_errno = errno;
303            }
304    }
305
306    /* Adjust i for the case where it was still withing the recs[] */
307    if (i < fstab->num_entries) --i;
308
309    *end_idx = i;
310    if (!mounted) {
311        *attempted_idx = start_idx;
312        errno = mount_errno;
313        return -1;
314    }
315    return 0;
316}
317
318/* When multiple fstab records share the same mount_point, it will
319 * try to mount each one in turn, and ignore any duplicates after a
320 * first successful mount.
321 * Returns -1 on error, and  FS_MGR_MNTALL_* otherwise.
322 */
323int fs_mgr_mount_all(struct fstab *fstab)
324{
325    int i = 0;
326    int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTED;
327    int error_count = 0;
328    int mret = -1;
329    int mount_errno = 0;
330    int attempted_idx = -1;
331
332    if (!fstab) {
333        return -1;
334    }
335
336    for (i = 0; i < fstab->num_entries; i++) {
337        /* Don't mount entries that are managed by vold */
338        if (fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) {
339            continue;
340        }
341
342        /* Skip swap and raw partition entries such as boot, recovery, etc */
343        if (!strcmp(fstab->recs[i].fs_type, "swap") ||
344            !strcmp(fstab->recs[i].fs_type, "emmc") ||
345            !strcmp(fstab->recs[i].fs_type, "mtd")) {
346            continue;
347        }
348
349        if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
350            wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
351        }
352
353        if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) &&
354            !device_is_debuggable()) {
355            if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) {
356                ERROR("Could not set up verified partition, skipping!\n");
357                continue;
358            }
359        }
360        int last_idx_inspected;
361        mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx);
362        i = last_idx_inspected;
363        mount_errno = errno;
364
365        /* Deal with encryptability. */
366        if (!mret) {
367            /* If this is encryptable, need to trigger encryption */
368            if ((fstab->recs[attempted_idx].fs_mgr_flags & MF_FORCECRYPT)) {
369                if (umount(fstab->recs[attempted_idx].mount_point) == 0) {
370                    if (encryptable == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
371                        ERROR("Will try to encrypt %s %s\n", fstab->recs[attempted_idx].mount_point,
372                              fstab->recs[attempted_idx].fs_type);
373                        encryptable = FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION;
374                    } else {
375                        ERROR("Only one encryptable/encrypted partition supported\n");
376                        encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
377                    }
378                } else {
379                    INFO("Could not umount %s - allow continue unencrypted\n",
380                         fstab->recs[attempted_idx].mount_point);
381                    continue;
382                }
383            }
384            /* Success!  Go get the next one */
385            continue;
386        }
387
388        /* mount(2) returned an error, check if it's encryptable and deal with it */
389        if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
390            fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
391            if(partition_wiped(fstab->recs[attempted_idx].blk_device)) {
392                ERROR("%s(): %s is wiped and %s %s is encryptable. Suggest recovery...\n", __func__,
393                      fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
394                      fstab->recs[attempted_idx].fs_type);
395                encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
396                continue;
397            } else {
398                /* Need to mount a tmpfs at this mountpoint for now, and set
399                 * properties that vold will query later for decrypting
400                 */
401                ERROR("%s(): possibly an encryptable blkdev %s for mount %s type %s )\n", __func__,
402                      fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
403                      fstab->recs[attempted_idx].fs_type);
404                if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) {
405                    ++error_count;
406                    continue;
407                }
408            }
409            encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
410        } else {
411            ERROR("Failed to mount an un-encryptable or wiped partition on"
412                   "%s at %s options: %s error: %s\n",
413                   fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
414                   fstab->recs[attempted_idx].fs_options, strerror(mount_errno));
415            ++error_count;
416            continue;
417        }
418    }
419
420    if (error_count) {
421        return -1;
422    } else {
423        return encryptable;
424    }
425}
426
427/* If tmp_mount_point is non-null, mount the filesystem there.  This is for the
428 * tmp mount we do to check the user password
429 * If multiple fstab entries are to be mounted on "n_name", it will try to mount each one
430 * in turn, and stop on 1st success, or no more match.
431 */
432int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device,
433                    char *tmp_mount_point)
434{
435    int i = 0;
436    int ret = -1;
437    int mount_errors = 0;
438    int first_mount_errno = 0;
439    char *m;
440
441    if (!fstab) {
442        return ret;
443    }
444
445    for (i = 0; i < fstab->num_entries; i++) {
446        if (!fs_match(fstab->recs[i].mount_point, n_name)) {
447            continue;
448        }
449
450        /* We found our match */
451        /* If this swap or a raw partition, report an error */
452        if (!strcmp(fstab->recs[i].fs_type, "swap") ||
453            !strcmp(fstab->recs[i].fs_type, "emmc") ||
454            !strcmp(fstab->recs[i].fs_type, "mtd")) {
455            ERROR("Cannot mount filesystem of type %s on %s\n",
456                  fstab->recs[i].fs_type, n_blk_device);
457            goto out;
458        }
459
460        /* First check the filesystem if requested */
461        if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
462            wait_for_file(n_blk_device, WAIT_TIMEOUT);
463        }
464
465        if (fstab->recs[i].fs_mgr_flags & MF_CHECK) {
466            check_fs(n_blk_device, fstab->recs[i].fs_type,
467                     fstab->recs[i].mount_point);
468        }
469
470        if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) &&
471            !device_is_debuggable()) {
472            if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) {
473                ERROR("Could not set up verified partition, skipping!\n");
474                continue;
475            }
476        }
477
478        /* Now mount it where requested */
479        if (tmp_mount_point) {
480            m = tmp_mount_point;
481        } else {
482            m = fstab->recs[i].mount_point;
483        }
484        if (__mount(n_blk_device, m, &fstab->recs[i])) {
485            if (!first_mount_errno) first_mount_errno = errno;
486            mount_errors++;
487            continue;
488        } else {
489            ret = 0;
490            goto out;
491        }
492    }
493    if (mount_errors) {
494        ERROR("Cannot mount filesystem on %s at %s. error: %s\n",
495            n_blk_device, m, strerror(first_mount_errno));
496        ret = -1;
497    } else {
498        /* We didn't find a match, say so and return an error */
499        ERROR("Cannot find mount point %s in fstab\n", fstab->recs[i].mount_point);
500    }
501
502out:
503    return ret;
504}
505
506/*
507 * mount a tmpfs filesystem at the given point.
508 * return 0 on success, non-zero on failure.
509 */
510int fs_mgr_do_tmpfs_mount(char *n_name)
511{
512    int ret;
513
514    ret = mount("tmpfs", n_name, "tmpfs",
515                MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS);
516    if (ret < 0) {
517        ERROR("Cannot mount tmpfs filesystem at %s\n", n_name);
518        return -1;
519    }
520
521    /* Success */
522    return 0;
523}
524
525int fs_mgr_unmount_all(struct fstab *fstab)
526{
527    int i = 0;
528    int ret = 0;
529
530    if (!fstab) {
531        return -1;
532    }
533
534    while (fstab->recs[i].blk_device) {
535        if (umount(fstab->recs[i].mount_point)) {
536            ERROR("Cannot unmount filesystem at %s\n", fstab->recs[i].mount_point);
537            ret = -1;
538        }
539        i++;
540    }
541
542    return ret;
543}
544
545/* This must be called after mount_all, because the mkswap command needs to be
546 * available.
547 */
548int fs_mgr_swapon_all(struct fstab *fstab)
549{
550    int i = 0;
551    int flags = 0;
552    int err = 0;
553    int ret = 0;
554    int status;
555    char *mkswap_argv[2] = {
556        MKSWAP_BIN,
557        NULL
558    };
559
560    if (!fstab) {
561        return -1;
562    }
563
564    for (i = 0; i < fstab->num_entries; i++) {
565        /* Skip non-swap entries */
566        if (strcmp(fstab->recs[i].fs_type, "swap")) {
567            continue;
568        }
569
570        if (fstab->recs[i].zram_size > 0) {
571            /* A zram_size was specified, so we need to configure the
572             * device.  There is no point in having multiple zram devices
573             * on a system (all the memory comes from the same pool) so
574             * we can assume the device number is 0.
575             */
576            FILE *zram_fp;
577
578            zram_fp = fopen(ZRAM_CONF_DEV, "r+");
579            if (zram_fp == NULL) {
580                ERROR("Unable to open zram conf device %s\n", ZRAM_CONF_DEV);
581                ret = -1;
582                continue;
583            }
584            fprintf(zram_fp, "%d\n", fstab->recs[i].zram_size);
585            fclose(zram_fp);
586        }
587
588        if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
589            wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
590        }
591
592        /* Initialize the swap area */
593        mkswap_argv[1] = fstab->recs[i].blk_device;
594        err = android_fork_execvp_ext(ARRAY_SIZE(mkswap_argv), mkswap_argv,
595                                      &status, true, LOG_KLOG, false, NULL);
596        if (err) {
597            ERROR("mkswap failed for %s\n", fstab->recs[i].blk_device);
598            ret = -1;
599            continue;
600        }
601
602        /* If -1, then no priority was specified in fstab, so don't set
603         * SWAP_FLAG_PREFER or encode the priority */
604        if (fstab->recs[i].swap_prio >= 0) {
605            flags = (fstab->recs[i].swap_prio << SWAP_FLAG_PRIO_SHIFT) &
606                    SWAP_FLAG_PRIO_MASK;
607            flags |= SWAP_FLAG_PREFER;
608        } else {
609            flags = 0;
610        }
611        err = swapon(fstab->recs[i].blk_device, flags);
612        if (err) {
613            ERROR("swapon failed for %s\n", fstab->recs[i].blk_device);
614            ret = -1;
615        }
616    }
617
618    return ret;
619}
620
621/*
622 * key_loc must be at least PROPERTY_VALUE_MAX bytes long
623 *
624 * real_blk_device must be at least PROPERTY_VALUE_MAX bytes long
625 */
626int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc, char *real_blk_device, int size)
627{
628    int i = 0;
629
630    if (!fstab) {
631        return -1;
632    }
633    /* Initialize return values to null strings */
634    if (key_loc) {
635        *key_loc = '\0';
636    }
637    if (real_blk_device) {
638        *real_blk_device = '\0';
639    }
640
641    /* Look for the encryptable partition to find the data */
642    for (i = 0; i < fstab->num_entries; i++) {
643        /* Don't deal with vold managed enryptable partitions here */
644        if (fstab->recs[i].fs_mgr_flags & MF_VOLDMANAGED) {
645            continue;
646        }
647        if (!(fstab->recs[i].fs_mgr_flags & (MF_CRYPT | MF_FORCECRYPT))) {
648            continue;
649        }
650
651        /* We found a match */
652        if (key_loc) {
653            strlcpy(key_loc, fstab->recs[i].key_loc, size);
654        }
655        if (real_blk_device) {
656            strlcpy(real_blk_device, fstab->recs[i].blk_device, size);
657        }
658        break;
659    }
660
661    return 0;
662}
663