Adding e4crypt support
Add file encryption flag to fstab. If file encryption flag set in fstab, handle identically to block encrypted volumes. Requires matching change: https://googleplex-android-review.git.corp.google.com/#/c/642778/ Change-Id: I28c236959f2d7d5f0dccc8ea45c325ea0cf871fc
This commit is contained in:
parent
631945200e
commit
6095afc115
|
@ -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,20 @@ 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
|
||||
&& encryptable != FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
|
||||
ERROR("Only one encryptable/encrypted partition supported\n");
|
||||
}
|
||||
|
||||
encryptable = status;
|
||||
|
||||
/* Success! Go get the next one */
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -60,6 +60,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 },
|
||||
|
@ -409,32 +410,37 @@ 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;
|
||||
}
|
||||
|
||||
int fs_mgr_is_notrim(struct fstab_rec *fstab)
|
||||
int fs_mgr_is_notrim(const struct fstab_rec *fstab)
|
||||
{
|
||||
return fstab->fs_mgr_flags & MF_NOTRIM;
|
||||
}
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
#define MF_NOEMULATEDSD 0x800 /* no emulated sdcard daemon, sd card is the only
|
||||
external storage */
|
||||
#define MF_NOTRIM 0x1000
|
||||
#define MF_FILEENCRYPTION 0x2000
|
||||
|
||||
#define DM_BUF_SIZE 4096
|
||||
|
||||
|
|
|
@ -73,10 +73,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
|
||||
|
@ -93,12 +96,13 @@ 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_notrim(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_is_notrim(const struct fstab_rec *fstab);
|
||||
int fs_mgr_swapon_all(struct fstab *fstab);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -46,7 +46,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)
|
||||
|
@ -57,11 +57,13 @@ LOCAL_STATIC_LIBRARIES := \
|
|||
liblogwrap \
|
||||
libcutils \
|
||||
libbase \
|
||||
libext4_utils_static \
|
||||
libutils \
|
||||
liblog \
|
||||
libc \
|
||||
libselinux \
|
||||
libmincrypt \
|
||||
libext4_utils_static
|
||||
libc++_static
|
||||
|
||||
# Create symlinks
|
||||
LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \
|
||||
|
|
|
@ -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 {
|
||||
|
@ -514,6 +515,36 @@ 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)) {
|
||||
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 +897,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;
|
||||
}
|
||||
|
|
|
@ -151,6 +151,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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -231,6 +231,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
|
||||
|
@ -309,6 +311,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
|
||||
|
||||
|
@ -444,6 +454,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
|
||||
|
||||
|
|
Loading…
Reference in New Issue