diff options
author | Paul Lawrence <paullawrence@google.com> | 2015-03-26 15:49:42 +0000 |
---|---|---|
committer | Paul Lawrence <paullawrence@google.com> | 2015-03-31 13:02:13 -0700 |
commit | b8c9d273a07f3fc45780e763bb3f7f6266b8cab7 (patch) | |
tree | 0f3f3070a9f3e447393e97116917348b1d9aa49d | |
parent | 934102baf8fca57abf63df7f134e977e696722db (diff) | |
download | system_core-b8c9d273a07f3fc45780e763bb3f7f6266b8cab7.zip system_core-b8c9d273a07f3fc45780e763bb3f7f6266b8cab7.tar.gz system_core-b8c9d273a07f3fc45780e763bb3f7f6266b8cab7.tar.bz2 |
Revert "Revert "Adding e4crypt support""
Fix build break caused by original change
This reverts commit 84b0bab58fcc7f225e9a17a15c531b0c2fc509c5.
Change-Id: I99fbd7c3d1ed92db1f546033c8493bb71a327924
-rw-r--r-- | fs_mgr/fs_mgr.c | 98 | ||||
-rw-r--r-- | fs_mgr/fs_mgr_fstab.c | 16 | ||||
-rw-r--r-- | fs_mgr/fs_mgr_priv.h | 1 | ||||
-rw-r--r-- | fs_mgr/include/fs_mgr.h | 14 | ||||
-rw-r--r-- | init/Android.mk | 7 | ||||
-rw-r--r-- | init/builtins.cpp | 54 | ||||
-rw-r--r-- | init/init_parser.cpp | 1 | ||||
-rw-r--r-- | init/keywords.h | 2 | ||||
-rw-r--r-- | rootdir/init.rc | 11 |
9 files changed, 174 insertions, 30 deletions
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c index d4daed6..273a2ec 100644 --- a/fs_mgr/fs_mgr.c +++ b/fs_mgr/fs_mgr.c @@ -31,6 +31,7 @@ #include <dirent.h> #include <ext4.h> #include <ext4_sb.h> +#include <ext4_crypt.h> #include <linux/loop.h> #include <private/android_filesystem_config.h> @@ -428,6 +429,73 @@ out: return ret; } +// Check to see if a mountable volume has encryption requirements +static int handle_encryptable(struct fstab *fstab, const struct fstab_rec* rec) +{ + /* If this is block encryptable, need to trigger encryption */ + if ( (rec->fs_mgr_flags & MF_FORCECRYPT) + || (device_is_force_encrypted() && fs_mgr_is_encryptable(rec))) { + if (umount(rec->mount_point) == 0) { + return FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION; + } else { + WARNING("Could not umount %s (%s) - allow continue unencrypted\n", + rec->mount_point, strerror(errno)); + return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED; + } + } + + // Deal with file level encryption + if (rec->fs_mgr_flags & MF_FILEENCRYPTION) { + // Default or not yet initialized encryption requires no more work here + if (!e4crypt_non_default_key(rec->mount_point)) { + INFO("%s is default file encrypted\n", rec->mount_point); + return FS_MGR_MNTALL_DEV_DEFAULT_FILE_ENCRYPTED; + } + + INFO("%s is non-default file encrypted\n", rec->mount_point); + + // Uses non-default key, so must unmount and set up temp file system + if (umount(rec->mount_point)) { + ERROR("Failed to umount %s - rebooting\n", rec->mount_point); + return FS_MGR_MNTALL_FAIL; + } + + if (fs_mgr_do_tmpfs_mount(rec->mount_point) != 0) { + ERROR("Failed to mount a tmpfs at %s\n", rec->mount_point); + return FS_MGR_MNTALL_FAIL; + } + + // Mount data temporarily so we can access unencrypted dir + char tmp_mnt[PATH_MAX]; + strlcpy(tmp_mnt, rec->mount_point, sizeof(tmp_mnt)); + strlcat(tmp_mnt, "/tmp_mnt", sizeof(tmp_mnt)); + if (mkdir(tmp_mnt, 0700)) { + ERROR("Failed to create temp mount point\n"); + return FS_MGR_MNTALL_FAIL; + } + + if (fs_mgr_do_mount(fstab, rec->mount_point, + rec->blk_device, tmp_mnt)) { + ERROR("Error temp mounting encrypted file system\n"); + return FS_MGR_MNTALL_FAIL; + } + + // Link it to the normal place so ext4_crypt functions work normally + strlcat(tmp_mnt, "/unencrypted", sizeof(tmp_mnt)); + char link_path[PATH_MAX]; + strlcpy(link_path, rec->mount_point, sizeof(link_path)); + strlcat(link_path, "/unencrypted", sizeof(link_path)); + if (symlink(tmp_mnt, link_path)) { + ERROR("Error creating symlink to unencrypted directory\n"); + return FS_MGR_MNTALL_FAIL; + } + + return FS_MGR_MNTALL_DEV_NON_DEFAULT_FILE_ENCRYPTED; + } + + return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED; +} + /* 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. @@ -490,25 +558,21 @@ int fs_mgr_mount_all(struct fstab *fstab) /* Deal with encryptability. */ if (!mret) { - /* If this is encryptable, need to trigger encryption */ - if ( (fstab->recs[attempted_idx].fs_mgr_flags & MF_FORCECRYPT) - || (device_is_force_encrypted() - && fs_mgr_is_encryptable(&fstab->recs[attempted_idx]))) { - if (umount(fstab->recs[attempted_idx].mount_point) == 0) { - if (encryptable == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) { - ERROR("Will try to encrypt %s %s\n", fstab->recs[attempted_idx].mount_point, - fstab->recs[attempted_idx].fs_type); - encryptable = FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION; - } else { - ERROR("Only one encryptable/encrypted partition supported\n"); - encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED; - } - } else { - WARNING("Could not umount %s (%s) - allow continue unencrypted\n", - fstab->recs[attempted_idx].mount_point, strerror(errno)); - continue; + int status = handle_encryptable(fstab, &fstab->recs[attempted_idx]); + + if (status == FS_MGR_MNTALL_FAIL) { + /* Fatal error - no point continuing */ + return status; + } + + 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; } diff --git a/fs_mgr/fs_mgr_fstab.c b/fs_mgr/fs_mgr_fstab.c index 2c3c90d..8b0f714 100644 --- a/fs_mgr/fs_mgr_fstab.c +++ b/fs_mgr/fs_mgr_fstab.c @@ -61,6 +61,7 @@ static struct flag_list fs_mgr_flags[] = { { "check", MF_CHECK }, { "encryptable=",MF_CRYPT }, { "forceencrypt=",MF_FORCECRYPT }, + { "fileencryption",MF_FILEENCRYPTION }, { "nonremovable",MF_NONREMOVABLE }, { "voldmanaged=",MF_VOLDMANAGED}, { "length=", MF_LENGTH }, @@ -418,27 +419,32 @@ struct fstab_rec *fs_mgr_get_entry_for_mount_point(struct fstab *fstab, const ch return fs_mgr_get_entry_for_mount_point_after(NULL, fstab, path); } -int fs_mgr_is_voldmanaged(struct fstab_rec *fstab) +int fs_mgr_is_voldmanaged(const struct fstab_rec *fstab) { return fstab->fs_mgr_flags & MF_VOLDMANAGED; } -int fs_mgr_is_nonremovable(struct fstab_rec *fstab) +int fs_mgr_is_nonremovable(const struct fstab_rec *fstab) { return fstab->fs_mgr_flags & MF_NONREMOVABLE; } -int fs_mgr_is_verified(struct fstab_rec *fstab) +int fs_mgr_is_verified(const struct fstab_rec *fstab) { return fstab->fs_mgr_flags & MF_VERIFY; } -int fs_mgr_is_encryptable(struct fstab_rec *fstab) +int fs_mgr_is_encryptable(const struct fstab_rec *fstab) { return fstab->fs_mgr_flags & (MF_CRYPT | MF_FORCECRYPT); } -int fs_mgr_is_noemulatedsd(struct fstab_rec *fstab) +int fs_mgr_is_file_encrypted(const struct fstab_rec *fstab) +{ + return fstab->fs_mgr_flags & MF_FILEENCRYPTION; +} + +int fs_mgr_is_noemulatedsd(const struct fstab_rec *fstab) { return fstab->fs_mgr_flags & MF_NOEMULATEDSD; } diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h index 88a1040..d56111a 100644 --- a/fs_mgr/fs_mgr_priv.h +++ b/fs_mgr/fs_mgr_priv.h @@ -76,6 +76,7 @@ #define MF_FORCECRYPT 0x400 #define MF_NOEMULATEDSD 0x800 /* no emulated sdcard daemon, sd card is the only external storage */ +#define MF_FILEENCRYPTION 0x2000 #define DM_BUF_SIZE 4096 diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h index ad8a8fc..b5e02f9 100644 --- a/fs_mgr/include/fs_mgr.h +++ b/fs_mgr/include/fs_mgr.h @@ -74,10 +74,13 @@ typedef void (*fs_mgr_verity_state_callback)(struct fstab_rec *fstab, struct fstab *fs_mgr_read_fstab(const char *fstab_path); void fs_mgr_free_fstab(struct fstab *fstab); +#define FS_MGR_MNTALL_DEV_NON_DEFAULT_FILE_ENCRYPTED 5 +#define FS_MGR_MNTALL_DEV_DEFAULT_FILE_ENCRYPTED 4 #define FS_MGR_MNTALL_DEV_NEEDS_RECOVERY 3 #define FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION 2 #define FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED 1 #define FS_MGR_MNTALL_DEV_NOT_ENCRYPTED 0 +#define FS_MGR_MNTALL_FAIL -1 int fs_mgr_mount_all(struct fstab *fstab); #define FS_MGR_DOMNT_FAILED -1 @@ -94,11 +97,12 @@ int fs_mgr_add_entry(struct fstab *fstab, const char *mount_point, const char *fs_type, const char *blk_device); struct fstab_rec *fs_mgr_get_entry_for_mount_point(struct fstab *fstab, const char *path); -int fs_mgr_is_voldmanaged(struct fstab_rec *fstab); -int fs_mgr_is_nonremovable(struct fstab_rec *fstab); -int fs_mgr_is_verified(struct fstab_rec *fstab); -int fs_mgr_is_encryptable(struct fstab_rec *fstab); -int fs_mgr_is_noemulatedsd(struct fstab_rec *fstab); +int fs_mgr_is_voldmanaged(const struct fstab_rec *fstab); +int fs_mgr_is_nonremovable(const struct fstab_rec *fstab); +int fs_mgr_is_verified(const struct fstab_rec *fstab); +int fs_mgr_is_encryptable(const struct fstab_rec *fstab); +int fs_mgr_is_file_encrypted(const struct fstab_rec *fstab); +int fs_mgr_is_noemulatedsd(const struct fstab_rec *fstab); int fs_mgr_swapon_all(struct fstab *fstab); #ifdef __cplusplus } diff --git a/init/Android.mk b/init/Android.mk index cb4cb11..dd867cb 100644 --- a/init/Android.mk +++ b/init/Android.mk @@ -47,7 +47,7 @@ LOCAL_SRC_FILES:= \ watchdogd.cpp \ LOCAL_MODULE:= init - +LOCAL_C_INCLUDES += system/extras/ext4_utils LOCAL_FORCE_STATIC_EXECUTABLE := true LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED) @@ -58,11 +58,14 @@ LOCAL_STATIC_LIBRARIES := \ liblogwrap \ libcutils \ libbase \ + libext4_utils_static \ + libutils \ liblog \ libc \ libselinux \ libmincrypt \ - libext4_utils_static + libc++_static \ + libdl # Create symlinks LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \ diff --git a/init/builtins.cpp b/init/builtins.cpp index 6daea37..9d5b8a8 100644 --- a/init/builtins.cpp +++ b/init/builtins.cpp @@ -29,6 +29,7 @@ #include <sys/wait.h> #include <unistd.h> #include <linux/loop.h> +#include <ext4_crypt.h> #include <selinux/selinux.h> #include <selinux/label.h> @@ -302,7 +303,7 @@ int do_mkdir(int nargs, char **args) } } - return 0; + return e4crypt_set_directory_policy(args[1]); } static struct { @@ -446,6 +447,17 @@ static int wipe_data_via_recovery() while (1) { pause(); } // never reached } +/* + * Callback to make a directory from the ext4 code + */ +static int do_mount_alls_make_dir(const char* dir) +{ + if (make_dir(dir, 0700) && errno != EEXIST) { + return -1; + } + + return 0; +} /* * This function might request a reboot, in which case it will @@ -514,6 +526,37 @@ int do_mount_all(int nargs, char **args) ERROR("fs_mgr_mount_all suggested recovery, so wiping data via recovery.\n"); ret = wipe_data_via_recovery(); /* If reboot worked, there is no return. */ + } else if (ret == FS_MGR_MNTALL_DEV_DEFAULT_FILE_ENCRYPTED) { + // We have to create the key files here. Only init can call make_dir, + // and we can't do it from fs_mgr as then fs_mgr would depend on + // make_dir creating a circular dependency. + fstab = fs_mgr_read_fstab(args[1]); + for (int i = 0; i < fstab->num_entries; ++i) { + if (fs_mgr_is_file_encrypted(&fstab->recs[i])) { + if (e4crypt_create_device_key(fstab->recs[i].mount_point, + do_mount_alls_make_dir)) { + ERROR("Could not create device key on %s" + " - continue unencrypted\n", + fstab->recs[i].mount_point); + } + } + } + fs_mgr_free_fstab(fstab); + + if (e4crypt_install_keyring()) { + return -1; + } + property_set("ro.crypto.state", "encrypted"); + + // Although encrypted, we have device key, so we do not need to + // do anything different from the nonencrypted case. + action_for_each_trigger("nonencrypted", action_add_queue_tail); + } else if (ret == FS_MGR_MNTALL_DEV_NON_DEFAULT_FILE_ENCRYPTED) { + if (e4crypt_install_keyring()) { + return -1; + } + property_set("ro.crypto.state", "encrypted"); + property_set("vold.decrypt", "trigger_restart_min_framework"); } else if (ret > 0) { ERROR("fs_mgr_mount_all returned unexpected error %d\n", ret); } @@ -866,3 +909,12 @@ int do_wait(int nargs, char **args) } else return -1; } + +int do_installkey(int nargs, char **args) +{ + if (nargs == 2) { + return e4crypt_install_key(args[1]); + } + + return -1; +} diff --git a/init/init_parser.cpp b/init/init_parser.cpp index 294dc19..4e18e20 100644 --- a/init/init_parser.cpp +++ b/init/init_parser.cpp @@ -153,6 +153,7 @@ static int lookup_keyword(const char *s) if (!strcmp(s, "fup")) return K_ifup; if (!strcmp(s, "nsmod")) return K_insmod; if (!strcmp(s, "mport")) return K_import; + if (!strcmp(s, "nstallkey")) return K_installkey; break; case 'k': if (!strcmp(s, "eycodes")) return K_keycodes; diff --git a/init/keywords.h b/init/keywords.h index 09f645b..34cb2ad 100644 --- a/init/keywords.h +++ b/init/keywords.h @@ -11,6 +11,7 @@ int do_export(int nargs, char **args); int do_hostname(int nargs, char **args); int do_ifup(int nargs, char **args); int do_insmod(int nargs, char **args); +int do_installkey(int nargs, char **args); int do_mkdir(int nargs, char **args); int do_mount_all(int nargs, char **args); int do_mount(int nargs, char **args); @@ -61,6 +62,7 @@ enum { KEYWORD(hostname, COMMAND, 1, do_hostname) KEYWORD(ifup, COMMAND, 1, do_ifup) KEYWORD(insmod, COMMAND, 1, do_insmod) + KEYWORD(installkey, COMMAND, 1, do_installkey) KEYWORD(import, SECTION, 1, 0) KEYWORD(keycodes, OPTION, 0, 0) KEYWORD(mkdir, COMMAND, 1, do_mkdir) diff --git a/rootdir/init.rc b/rootdir/init.rc index 3ae0954..cda79ce 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -225,6 +225,8 @@ on post-fs mkdir /cache/lost+found 0770 root root on post-fs-data + installkey /data + # We chown/chmod /data again so because mount is run as root + defaults chown system system /data chmod 0771 /data @@ -303,6 +305,14 @@ on post-fs-data # Separate location for storing security policy files on data mkdir /data/security 0711 system system + # Create all remaining /data root dirs so that they are made through init + # and get proper encryption policy installed + mkdir /data/backup 0700 system system + mkdir /data/media 0770 media_rw media_rw + mkdir /data/ss 0700 system system + mkdir /data/system 0775 system system + mkdir /data/user 0711 system system + # Reload policy from /data/security if present. setprop selinux.reload_policy 1 @@ -438,6 +448,7 @@ on property:vold.decrypt=trigger_restart_min_framework class_start main on property:vold.decrypt=trigger_restart_framework + installkey /data class_start main class_start late_start |