diff options
Diffstat (limited to 'fs_mgr/fs_mgr.c')
-rw-r--r-- | fs_mgr/fs_mgr.c | 233 |
1 files changed, 157 insertions, 76 deletions
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c index 15d44ef..e78b581 100644 --- a/fs_mgr/fs_mgr.c +++ b/fs_mgr/fs_mgr.c @@ -39,6 +39,7 @@ #include <cutils/partition_utils.h> #include <cutils/properties.h> #include <logwrap/logwrap.h> +#include <blkid/blkid.h> #include "mincrypt/rsa.h" #include "mincrypt/sha.h" @@ -60,6 +61,7 @@ #define FSCK_LOG_FILE "/dev/fscklogs/log" #define ZRAM_CONF_DEV "/sys/block/zram0/disksize" +#define ZRAM_STREAMS "/sys/block/zram0/max_comp_streams" #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) @@ -161,10 +163,10 @@ static void check_fs(char *blk_device, char *fs_type, char *target) } else if (!strcmp(fs_type, "f2fs")) { char *f2fs_fsck_argv[] = { F2FS_FSCK_BIN, - "-f", + "-a", blk_device }; - INFO("Running %s -f %s\n", F2FS_FSCK_BIN, blk_device); + INFO("Running %s -a %s\n", F2FS_FSCK_BIN, blk_device); ret = android_fork_execvp_ext(ARRAY_SIZE(f2fs_fsck_argv), f2fs_fsck_argv, &status, true, LOG_KLOG | LOG_FILE, @@ -304,6 +306,8 @@ static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_ int i; int mount_errno = 0; int mounted = 0; + int cmp_len; + char *detected_fs_type; if (!end_idx || !attempted_idx || start_idx >= fstab->num_entries) { errno = EINVAL; @@ -329,8 +333,16 @@ static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_ } if (fstab->recs[i].fs_mgr_flags & MF_CHECK) { - check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type, - fstab->recs[i].mount_point); + /* Skip file system check unless we are sure we are the right type */ + detected_fs_type = blkid_get_tag_value(NULL, "TYPE", fstab->recs[i].blk_device); + if (detected_fs_type) { + cmp_len = (!strncmp(detected_fs_type, "ext", 3) && + strlen(detected_fs_type) == 4) ? 3 : strlen(detected_fs_type); + if (!strncmp(fstab->recs[i].fs_type, detected_fs_type, cmp_len)) { + check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type, + fstab->recs[i].mount_point); + } + } } if (!__mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point, &fstab->recs[i])) { *attempted_idx = i; @@ -492,6 +504,52 @@ static int handle_encryptable(struct fstab *fstab, const struct fstab_rec* rec) return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED; } +/* + * Reads the kernel cmdline to check if MDTP is activated. + * When MDTP is activated, kernel cmdline will have the word 'mdtp'. + */ +int fs_mgr_is_mdtp_activated() +{ + char cmdline[2048]; + char *ptr; + int fd; + static int mdtp_activated = 0; + static int mdtp_activated_set = 0; + + if (mdtp_activated_set) { + return mdtp_activated; + } + + fd = open("/proc/cmdline", O_RDONLY); + if (fd >= 0) { + int n = read(fd, cmdline, sizeof(cmdline) - 1); + if (n < 0) n = 0; + + /* get rid of trailing newline, it happens */ + if (n > 0 && cmdline[n-1] == '\n') n--; + + cmdline[n] = 0; + close(fd); + } else { + cmdline[0] = 0; + } + + ptr = cmdline; + while (ptr && *ptr) { + char *x = strchr(ptr, ' '); + if (x != 0) *x++ = 0; + if (!strcmp(ptr,"mdtp")) { + mdtp_activated = 1; + break; + } + ptr = x; + } + + mdtp_activated_set = 1; + + return mdtp_activated; +} + /* When multiple fstab records share the same mount_point, it will * try to mount each one in turn, and ignore any duplicates after a * first successful mount. @@ -547,91 +605,106 @@ int fs_mgr_mount_all(struct fstab *fstab) continue; } } - int last_idx_inspected; - int top_idx = i; - mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx); - i = last_idx_inspected; - mount_errno = errno; + if (fs_mgr_is_mdtp_activated() && ((fstab->recs[i].fs_mgr_flags & MF_FORCECRYPT) || + device_is_force_encrypted())) { + INFO("%s(): mdtp activated, blkdev %s for mount %s type %s expected to be encrypted)\n", + __func__, fstab->recs[i].blk_device, fstab->recs[i].mount_point, + fstab->recs[i].fs_type); + if (fs_mgr_do_tmpfs_mount(fstab->recs[i].mount_point) < 0) { + ++error_count; + continue; + } - /* Deal with encryptability. */ - if (!mret) { - int status = handle_encryptable(fstab, &fstab->recs[attempted_idx]); + encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED; - if (status == FS_MGR_MNTALL_FAIL) { - /* Fatal error - no point continuing */ - return status; - } + } else { + int last_idx_inspected; + int top_idx = i; - if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) { - if (encryptable != FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) { - // Log and continue - ERROR("Only one encryptable/encrypted partition supported\n"); - } - encryptable = status; - } + mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx); + i = last_idx_inspected; + mount_errno = errno; - /* Success! Go get the next one */ - continue; - } + /* Deal with encryptability. */ + if (!mret) { + int status = handle_encryptable(fstab, &fstab->recs[attempted_idx]); - /* mount(2) returned an error, handle the encryptable/formattable case */ - bool wiped = partition_wiped(fstab->recs[top_idx].blk_device); - if (mret && mount_errno != EBUSY && mount_errno != EACCES && - fs_mgr_is_formattable(&fstab->recs[top_idx]) && wiped) { - /* top_idx and attempted_idx point at the same partition, but sometimes - * at two different lines in the fstab. Use the top one for formatting - * as that is the preferred one. - */ - ERROR("%s(): %s is wiped and %s %s is formattable. Format it.\n", __func__, - fstab->recs[top_idx].blk_device, fstab->recs[top_idx].mount_point, - fstab->recs[top_idx].fs_type); - if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) && - strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) { - int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY, 0644); - if (fd >= 0) { - INFO("%s(): also wipe %s\n", __func__, fstab->recs[top_idx].key_loc); - wipe_block_device(fd, get_file_size(fd)); - close(fd); - } else { - ERROR("%s(): %s wouldn't open (%s)\n", __func__, - fstab->recs[top_idx].key_loc, strerror(errno)); + if (status == FS_MGR_MNTALL_FAIL) { + /* Fatal error - no point continuing */ + return status; } - } - if (fs_mgr_do_format(&fstab->recs[top_idx]) == 0) { - /* Let's replay the mount actions. */ - i = top_idx - 1; + + if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) { + if (encryptable != FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) { + // Log and continue + ERROR("Only one encryptable/encrypted partition supported\n"); + } + encryptable = status; + } + + /* Success! Go get the next one */ continue; } - } - if (mret && mount_errno != EBUSY && mount_errno != EACCES && - fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) { - if (wiped) { - ERROR("%s(): %s is wiped and %s %s is encryptable. Suggest recovery...\n", __func__, - fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point, - fstab->recs[attempted_idx].fs_type); - encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY; - continue; - } else { - /* Need to mount a tmpfs at this mountpoint for now, and set - * properties that vold will query later for decrypting + + /* mount(2) returned an error, handle the encryptable/formattable case */ + bool wiped = partition_wiped(fstab->recs[top_idx].blk_device); + if (mret && mount_errno != EBUSY && mount_errno != EACCES && + fs_mgr_is_formattable(&fstab->recs[top_idx]) && wiped) { + /* top_idx and attempted_idx point at the same partition, but sometimes + * at two different lines in the fstab. Use the top one for formatting + * as that is the preferred one. */ - ERROR("%s(): possibly an encryptable blkdev %s for mount %s type %s )\n", __func__, - fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point, - fstab->recs[attempted_idx].fs_type); - if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) { - ++error_count; + ERROR("%s(): %s is wiped and %s %s is formattable. Format it.\n", __func__, + fstab->recs[top_idx].blk_device, fstab->recs[top_idx].mount_point, + fstab->recs[top_idx].fs_type); + if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) && + strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) { + int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY, 0644); + if (fd >= 0) { + INFO("%s(): also wipe %s\n", __func__, fstab->recs[top_idx].key_loc); + wipe_block_device(fd, get_file_size(fd)); + close(fd); + } else { + ERROR("%s(): %s wouldn't open (%s)\n", __func__, + fstab->recs[top_idx].key_loc, strerror(errno)); + } + } + if (fs_mgr_do_format(&fstab->recs[top_idx]) == 0) { + /* Let's replay the mount actions. */ + i = top_idx - 1; continue; } } - encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED; - } else { - ERROR("Failed to mount an un-encryptable or wiped partition on" - "%s at %s options: %s error: %s\n", - fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point, - fstab->recs[attempted_idx].fs_options, strerror(mount_errno)); - ++error_count; - continue; + if (mret && mount_errno != EBUSY && mount_errno != EACCES && + fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) { + if (wiped) { + ERROR("%s(): %s is wiped and %s %s is encryptable. Suggest recovery...\n", __func__, + fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point, + fstab->recs[attempted_idx].fs_type); + encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY; + continue; + } else { + /* Need to mount a tmpfs at this mountpoint for now, and set + * properties that vold will query later for decrypting + */ + ERROR("%s(): possibly an encryptable blkdev %s for mount %s type %s )\n", __func__, + fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point, + fstab->recs[attempted_idx].fs_type); + if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) { + ++error_count; + continue; + } + } + encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED; + } else { + ERROR("Failed to mount an un-encryptable or wiped partition on" + "%s at %s options: %s error: %s\n", + fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point, + fstab->recs[attempted_idx].fs_options, strerror(mount_errno)); + ++error_count; + continue; + } } } @@ -799,6 +872,14 @@ int fs_mgr_swapon_all(struct fstab *fstab) */ FILE *zram_fp; + /* The stream count parameter is only available on new kernels. + * It must be set before the disk size. */ + zram_fp = fopen(ZRAM_STREAMS, "r+"); + if (zram_fp) { + fprintf(zram_fp, "%d\n", fstab->recs[i].zram_streams); + fclose(zram_fp); + } + zram_fp = fopen(ZRAM_CONF_DEV, "r+"); if (zram_fp == NULL) { ERROR("Unable to open zram conf device %s\n", ZRAM_CONF_DEV); |