From e5032c42da3c33a854df0a24a7968b4ab54190b9 Mon Sep 17 00:00:00 2001 From: Ken Sumrall Date: Sun, 1 Apr 2012 23:58:44 -0700 Subject: [PATCH] Changes to encryption to work with the new filesystem manager The new filesystem manager is in charge of mounting the block devices now, removing much of the knowledge from init..rc. This also let us clean up some init code dealing with encryption, so this change updates vold to work with that. More cleanup is possible, but the main goal of the filesystem manager was to enable e2fsck, not a full cleanup of encryption. Change-Id: I00ea80a923d14770ed8fdd190e8840be195f8514 --- Android.mk | 4 ++ cryptfs.c | 119 ++++++++++++++++++++--------------------------------- 2 files changed, 48 insertions(+), 75 deletions(-) diff --git a/Android.mk b/Android.mk index e4256ae..b7a4905 100644 --- a/Android.mk +++ b/Android.mk @@ -40,6 +40,8 @@ LOCAL_C_INCLUDES := $(common_c_includes) LOCAL_SHARED_LIBRARIES := $(common_shared_libraries) +LOCAL_STATIC_LIBRARIES := libfs_mgr + LOCAL_MODULE_TAGS := eng tests include $(BUILD_STATIC_LIBRARY) @@ -58,6 +60,8 @@ LOCAL_CFLAGS := -Werror=format LOCAL_SHARED_LIBRARIES := $(common_shared_libraries) +LOCAL_STATIC_LIBRARIES := libfs_mgr + include $(BUILD_EXECUTABLE) include $(CLEAR_VARS) diff --git a/cryptfs.c b/cryptfs.c index 5bd6de7..cc7797a 100644 --- a/cryptfs.c +++ b/cryptfs.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "cryptfs.h" #define LOG_TAG "Cryptfs" #include "cutils/android_reboot.h" @@ -53,7 +54,6 @@ #define KEY_LEN_BYTES 16 #define IV_LEN_BYTES 16 -#define KEY_LOC_PROP "ro.crypto.keyfile.userdata" #define KEY_IN_FOOTER "footer" #define EXT4_FS 1 @@ -65,6 +65,8 @@ static unsigned char saved_master_key[KEY_LEN_BYTES]; static char *saved_data_blkdev; static char *saved_mount_point; static int master_key_saved = 0; +#define FSTAB_PREFIX "/fstab." +static char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)]; static void ioctl_init(struct dm_ioctl *io, size_t dataSize, const char *name, unsigned flags) { @@ -122,6 +124,19 @@ static unsigned int get_blkdev_size(int fd) return nr_sec; } +/* Get and cache the name of the fstab file so we don't + * keep talking over the socket to the property service. + */ +static char *get_fstab_filename(void) +{ + if (fstab_filename[0] == 0) { + strcpy(fstab_filename, FSTAB_PREFIX); + property_get("ro.hardware", fstab_filename + sizeof(FSTAB_PREFIX) - 1, ""); + } + + return fstab_filename; +} + /* key or salt can be NULL, in which case just skip writing that value. Useful to * update the failed mount count but not change the key. */ @@ -136,7 +151,7 @@ static int put_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *cryp char key_loc[PROPERTY_VALUE_MAX]; struct stat statbuf; - property_get(KEY_LOC_PROP, key_loc, KEY_IN_FOOTER); + fs_mgr_get_crypt_info(get_fstab_filename(), key_loc, 0, sizeof(key_loc)); if (!strcmp(key_loc, KEY_IN_FOOTER)) { fname = real_blk_name; @@ -167,7 +182,7 @@ static int put_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *cryp return -1; } } else { - SLOGE("Unexpected value for" KEY_LOC_PROP "\n"); + SLOGE("Unexpected value for crypto key location\n"); return -1;; } @@ -235,7 +250,7 @@ static int get_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *cryp char *fname; struct stat statbuf; - property_get(KEY_LOC_PROP, key_loc, KEY_IN_FOOTER); + fs_mgr_get_crypt_info(get_fstab_filename(), key_loc, 0, sizeof(key_loc)); if (!strcmp(key_loc, KEY_IN_FOOTER)) { fname = real_blk_name; @@ -273,7 +288,7 @@ static int get_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *cryp goto errout; } } else { - SLOGE("Unexpected value for" KEY_LOC_PROP "\n"); + SLOGE("Unexpected value for crypto key location\n"); return -1;; } @@ -557,27 +572,6 @@ static int create_encrypted_random_key(char *passwd, unsigned char *master_key, return encrypt_master_key(passwd, salt, key_buf, master_key); } -static int get_orig_mount_parms(char *mount_point, char *fs_type, char *real_blkdev, - unsigned long *mnt_flags, char *fs_options) -{ - char mount_point2[PROPERTY_VALUE_MAX]; - char fs_flags[PROPERTY_VALUE_MAX]; - - property_get("ro.crypto.fs_type", fs_type, ""); - property_get("ro.crypto.fs_real_blkdev", real_blkdev, ""); - property_get("ro.crypto.fs_mnt_point", mount_point2, ""); - property_get("ro.crypto.fs_options", fs_options, ""); - property_get("ro.crypto.fs_flags", fs_flags, ""); - *mnt_flags = strtol(fs_flags, 0, 0); - - if (strcmp(mount_point, mount_point2)) { - /* Consistency check. These should match. If not, something odd happened. */ - return -1; - } - - return 0; -} - static int wait_and_unmount(char *mountpoint) { int i, rc; @@ -692,26 +686,22 @@ int cryptfs_restart(void) return -1; } - if (! get_orig_mount_parms(DATA_MNT_POINT, fs_type, real_blkdev, &mnt_flags, fs_options)) { - SLOGD("Just got orig mount parms\n"); - - if (! (rc = wait_and_unmount(DATA_MNT_POINT)) ) { - /* If that succeeded, then mount the decrypted filesystem */ - mount(crypto_blkdev, DATA_MNT_POINT, fs_type, mnt_flags, fs_options); + if (! (rc = wait_and_unmount(DATA_MNT_POINT)) ) { + /* If that succeeded, then mount the decrypted filesystem */ + fs_mgr_do_mount(get_fstab_filename(), DATA_MNT_POINT, crypto_blkdev, 0); - property_set("vold.decrypt", "trigger_load_persist_props"); - /* Create necessary paths on /data */ - if (prep_data_fs()) { - return -1; - } + property_set("vold.decrypt", "trigger_load_persist_props"); + /* Create necessary paths on /data */ + if (prep_data_fs()) { + return -1; + } - /* startup service classes main and late_start */ - property_set("vold.decrypt", "trigger_restart_framework"); - SLOGD("Just triggered restart_framework\n"); + /* startup service classes main and late_start */ + property_set("vold.decrypt", "trigger_restart_framework"); + SLOGD("Just triggered restart_framework\n"); - /* Give it a few moments to get started */ - sleep(1); - } + /* Give it a few moments to get started */ + sleep(1); } if (rc == 0) { @@ -727,9 +717,6 @@ static int do_crypto_complete(char *mount_point) unsigned char encrypted_master_key[32]; unsigned char salt[SALT_LEN]; char real_blkdev[MAXPATHLEN]; - char fs_type[PROPERTY_VALUE_MAX]; - char fs_options[PROPERTY_VALUE_MAX]; - unsigned long mnt_flags; char encrypted_state[PROPERTY_VALUE_MAX]; char key_loc[PROPERTY_VALUE_MAX]; @@ -739,13 +726,11 @@ static int do_crypto_complete(char *mount_point) return 1; } - if (get_orig_mount_parms(mount_point, fs_type, real_blkdev, &mnt_flags, fs_options)) { - SLOGE("Error reading original mount parms for mount point %s\n", mount_point); - return -1; - } + fs_mgr_get_crypt_info(get_fstab_filename(), 0, real_blkdev, sizeof(real_blkdev)); if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt)) { - property_get(KEY_LOC_PROP, key_loc, KEY_IN_FOOTER); + fs_mgr_get_crypt_info(get_fstab_filename(), key_loc, 0, sizeof(key_loc)); + /* * Only report this error if key_loc is a file and it exists. * If the device was never encrypted, and /data is not mountable for @@ -780,10 +765,7 @@ static int test_mount_encrypted_fs(char *passwd, char *mount_point, char *label) unsigned char salt[SALT_LEN]; char crypto_blkdev[MAXPATHLEN]; char real_blkdev[MAXPATHLEN]; - char fs_type[PROPERTY_VALUE_MAX]; - char fs_options[PROPERTY_VALUE_MAX]; char tmp_mount_point[64]; - unsigned long mnt_flags; unsigned int orig_failed_decrypt_count; char encrypted_state[PROPERTY_VALUE_MAX]; int rc; @@ -794,10 +776,7 @@ static int test_mount_encrypted_fs(char *passwd, char *mount_point, char *label) return -1; } - if (get_orig_mount_parms(mount_point, fs_type, real_blkdev, &mnt_flags, fs_options)) { - SLOGE("Error reading original mount parms for mount point %s\n", mount_point); - return -1; - } + fs_mgr_get_crypt_info(get_fstab_filename(), 0, real_blkdev, sizeof(real_blkdev)); if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt)) { SLOGE("Error getting crypt footer and key\n"); @@ -826,7 +805,7 @@ static int test_mount_encrypted_fs(char *passwd, char *mount_point, char *label) */ sprintf(tmp_mount_point, "%s/tmp_mnt", mount_point); mkdir(tmp_mount_point, 0755); - if ( mount(crypto_blkdev, tmp_mount_point, "ext4", MS_RDONLY, "") ) { + if (fs_mgr_do_mount(get_fstab_filename(), DATA_MNT_POINT, crypto_blkdev, tmp_mount_point)) { SLOGE("Error temp mounting decrypted block device\n"); delete_crypto_blk_dev(label); crypt_ftr.failed_decrypt_count++; @@ -938,9 +917,6 @@ int cryptfs_verify_passwd(char *passwd) unsigned char encrypted_master_key[32], decrypted_master_key[32]; unsigned char salt[SALT_LEN]; char real_blkdev[MAXPATHLEN]; - char fs_type[PROPERTY_VALUE_MAX]; - char fs_options[PROPERTY_VALUE_MAX]; - unsigned long mnt_flags; char encrypted_state[PROPERTY_VALUE_MAX]; int rc; @@ -960,10 +936,7 @@ int cryptfs_verify_passwd(char *passwd) return -1; } - if (get_orig_mount_parms(saved_mount_point, fs_type, real_blkdev, &mnt_flags, fs_options)) { - SLOGE("Error reading original mount parms for mount point %s\n", saved_mount_point); - return -1; - } + fs_mgr_get_crypt_info(get_fstab_filename(), 0, real_blkdev, sizeof(real_blkdev)); if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt)) { SLOGE("Error getting crypt footer and key\n"); @@ -1143,9 +1116,7 @@ int cryptfs_enable(char *howarg, char *passwd) { int how = 0; char crypto_blkdev[MAXPATHLEN], real_blkdev[MAXPATHLEN], sd_crypto_blkdev[MAXPATHLEN]; - char fs_type[PROPERTY_VALUE_MAX], fs_options[PROPERTY_VALUE_MAX], - mount_point[PROPERTY_VALUE_MAX]; - unsigned long mnt_flags, nr_sec; + unsigned long nr_sec; unsigned char master_key[KEY_LEN_BYTES], decrypted_master_key[KEY_LEN_BYTES]; unsigned char salt[SALT_LEN]; int rc=-1, fd, i, ret; @@ -1167,7 +1138,7 @@ int cryptfs_enable(char *howarg, char *passwd) goto error_unencrypted; } - property_get(KEY_LOC_PROP, key_loc, KEY_IN_FOOTER); + fs_mgr_get_crypt_info(get_fstab_filename(), key_loc, 0, sizeof(key_loc)); if (!strcmp(howarg, "wipe")) { how = CRYPTO_ENABLE_WIPE; @@ -1178,7 +1149,7 @@ int cryptfs_enable(char *howarg, char *passwd) goto error_unencrypted; } - get_orig_mount_parms(mount_point, fs_type, real_blkdev, &mnt_flags, fs_options); + fs_mgr_get_crypt_info(get_fstab_filename(), 0, real_blkdev, sizeof(real_blkdev)); /* Get the size of the real block device */ fd = open(real_blkdev, O_RDONLY); @@ -1267,9 +1238,7 @@ int cryptfs_enable(char *howarg, char *passwd) * /data, set a property saying we're doing inplace encryption, * and restart the framework. */ - property_get("ro.crypto.tmpfs_options", tmpfs_options, ""); - if (mount("tmpfs", DATA_MNT_POINT, "tmpfs", MS_NOATIME | MS_NOSUID | MS_NODEV, - tmpfs_options) < 0) { + if (fs_mgr_do_tmpfs_mount(DATA_MNT_POINT)) { goto error_shutting_down; } /* Tells the framework that inplace encryption is starting */ @@ -1456,7 +1425,7 @@ int cryptfs_changepw(char *newpw) return -1; } - property_get("ro.crypto.fs_real_blkdev", real_blkdev, ""); + fs_mgr_get_crypt_info(get_fstab_filename(), 0, real_blkdev, sizeof(real_blkdev)); if (strlen(real_blkdev) == 0) { SLOGE("Can't find real blkdev"); return -1;