Add a mount with metadata encryption service
Don't use the FDE flow to support metadata encryption; just provide a vold service which directly mounts the volume and use that. Bug: 63927601 Test: Boot Taimen to SUW with and without metadata encryption. Change-Id: Ifc6a012c02c0ea66893020ed1d0da4cba6914aed
This commit is contained in:
parent
772cc85d71
commit
0fd2626fc3
10 changed files with 107 additions and 150 deletions
|
@ -73,6 +73,7 @@ struct encryptGroupsData
|
||||||
int completed;
|
int completed;
|
||||||
time_t time_started;
|
time_t time_started;
|
||||||
int remaining_time;
|
int remaining_time;
|
||||||
|
bool set_progress_properties;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void update_progress(struct encryptGroupsData* data, int is_used)
|
static void update_progress(struct encryptGroupsData* data, int is_used)
|
||||||
|
@ -88,6 +89,8 @@ static void update_progress(struct encryptGroupsData* data, int is_used)
|
||||||
data->new_pct = data->blocks_already_done / data->one_pct;
|
data->new_pct = data->blocks_already_done / data->one_pct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!data->set_progress_properties) return;
|
||||||
|
|
||||||
if (data->new_pct > data->cur_pct) {
|
if (data->new_pct > data->cur_pct) {
|
||||||
char buf[8];
|
char buf[8];
|
||||||
data->cur_pct = data->new_pct;
|
data->cur_pct = data->new_pct;
|
||||||
|
@ -253,7 +256,8 @@ errout:
|
||||||
|
|
||||||
static int cryptfs_enable_inplace_ext4(char* crypto_blkdev, char* real_blkdev, off64_t size,
|
static int cryptfs_enable_inplace_ext4(char* crypto_blkdev, char* real_blkdev, off64_t size,
|
||||||
off64_t* size_already_done, off64_t tot_size,
|
off64_t* size_already_done, off64_t tot_size,
|
||||||
off64_t previously_encrypted_upto) {
|
off64_t previously_encrypted_upto,
|
||||||
|
bool set_progress_properties) {
|
||||||
u32 i;
|
u32 i;
|
||||||
struct encryptGroupsData data;
|
struct encryptGroupsData data;
|
||||||
int rc; // Can't initialize without causing warning -Wclobbered
|
int rc; // Can't initialize without causing warning -Wclobbered
|
||||||
|
@ -268,13 +272,16 @@ static int cryptfs_enable_inplace_ext4(char* crypto_blkdev, char* real_blkdev, o
|
||||||
memset(&data, 0, sizeof(data));
|
memset(&data, 0, sizeof(data));
|
||||||
data.real_blkdev = real_blkdev;
|
data.real_blkdev = real_blkdev;
|
||||||
data.crypto_blkdev = crypto_blkdev;
|
data.crypto_blkdev = crypto_blkdev;
|
||||||
|
data.set_progress_properties = set_progress_properties;
|
||||||
|
|
||||||
|
LOG(DEBUG) << "Opening" << real_blkdev;
|
||||||
if ( (data.realfd = open(real_blkdev, O_RDWR|O_CLOEXEC)) < 0) {
|
if ( (data.realfd = open(real_blkdev, O_RDWR|O_CLOEXEC)) < 0) {
|
||||||
PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for inplace encrypt";
|
PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for inplace encrypt";
|
||||||
rc = -1;
|
rc = -1;
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG(DEBUG) << "Opening" << crypto_blkdev;
|
||||||
// Wait until the block device appears. Re-use the mount retry values since it is reasonable.
|
// Wait until the block device appears. Re-use the mount retry values since it is reasonable.
|
||||||
while ((data.cryptofd = open(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) {
|
while ((data.cryptofd = open(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) {
|
||||||
if (--retries) {
|
if (--retries) {
|
||||||
|
@ -390,7 +397,8 @@ static int encrypt_one_block_f2fs(u64 pos, void *data)
|
||||||
|
|
||||||
static int cryptfs_enable_inplace_f2fs(char* crypto_blkdev, char* real_blkdev, off64_t size,
|
static int cryptfs_enable_inplace_f2fs(char* crypto_blkdev, char* real_blkdev, off64_t size,
|
||||||
off64_t* size_already_done, off64_t tot_size,
|
off64_t* size_already_done, off64_t tot_size,
|
||||||
off64_t previously_encrypted_upto) {
|
off64_t previously_encrypted_upto,
|
||||||
|
bool set_progress_properties) {
|
||||||
struct encryptGroupsData data;
|
struct encryptGroupsData data;
|
||||||
struct f2fs_info *f2fs_info = NULL;
|
struct f2fs_info *f2fs_info = NULL;
|
||||||
int rc = ENABLE_INPLACE_ERR_OTHER;
|
int rc = ENABLE_INPLACE_ERR_OTHER;
|
||||||
|
@ -401,6 +409,7 @@ static int cryptfs_enable_inplace_f2fs(char* crypto_blkdev, char* real_blkdev, o
|
||||||
memset(&data, 0, sizeof(data));
|
memset(&data, 0, sizeof(data));
|
||||||
data.real_blkdev = real_blkdev;
|
data.real_blkdev = real_blkdev;
|
||||||
data.crypto_blkdev = crypto_blkdev;
|
data.crypto_blkdev = crypto_blkdev;
|
||||||
|
data.set_progress_properties = set_progress_properties;
|
||||||
data.realfd = -1;
|
data.realfd = -1;
|
||||||
data.cryptofd = -1;
|
data.cryptofd = -1;
|
||||||
if ( (data.realfd = open64(real_blkdev, O_RDWR|O_CLOEXEC)) < 0) {
|
if ( (data.realfd = open64(real_blkdev, O_RDWR|O_CLOEXEC)) < 0) {
|
||||||
|
@ -463,7 +472,8 @@ errout:
|
||||||
|
|
||||||
static int cryptfs_enable_inplace_full(char* crypto_blkdev, char* real_blkdev, off64_t size,
|
static int cryptfs_enable_inplace_full(char* crypto_blkdev, char* real_blkdev, off64_t size,
|
||||||
off64_t* size_already_done, off64_t tot_size,
|
off64_t* size_already_done, off64_t tot_size,
|
||||||
off64_t previously_encrypted_upto) {
|
off64_t previously_encrypted_upto,
|
||||||
|
bool set_progress_properties) {
|
||||||
int realfd, cryptofd;
|
int realfd, cryptofd;
|
||||||
char *buf[CRYPT_INPLACE_BUFSIZE];
|
char *buf[CRYPT_INPLACE_BUFSIZE];
|
||||||
int rc = ENABLE_INPLACE_ERR_OTHER;
|
int rc = ENABLE_INPLACE_ERR_OTHER;
|
||||||
|
@ -526,7 +536,7 @@ static int cryptfs_enable_inplace_full(char* crypto_blkdev, char* real_blkdev, o
|
||||||
/* process the majority of the filesystem in blocks */
|
/* process the majority of the filesystem in blocks */
|
||||||
for (i/=CRYPT_SECTORS_PER_BUFSIZE; i<numblocks; i++) {
|
for (i/=CRYPT_SECTORS_PER_BUFSIZE; i<numblocks; i++) {
|
||||||
new_pct = (i + blocks_already_done) / one_pct;
|
new_pct = (i + blocks_already_done) / one_pct;
|
||||||
if (new_pct > cur_pct) {
|
if (set_progress_properties && new_pct > cur_pct) {
|
||||||
char buf[8];
|
char buf[8];
|
||||||
|
|
||||||
cur_pct = new_pct;
|
cur_pct = new_pct;
|
||||||
|
@ -575,13 +585,17 @@ errout:
|
||||||
/* returns on of the ENABLE_INPLACE_* return codes */
|
/* returns on of the ENABLE_INPLACE_* return codes */
|
||||||
int cryptfs_enable_inplace(char* crypto_blkdev, char* real_blkdev, off64_t size,
|
int cryptfs_enable_inplace(char* crypto_blkdev, char* real_blkdev, off64_t size,
|
||||||
off64_t* size_already_done, off64_t tot_size,
|
off64_t* size_already_done, off64_t tot_size,
|
||||||
off64_t previously_encrypted_upto) {
|
off64_t previously_encrypted_upto, bool set_progress_properties) {
|
||||||
int rc_ext4, rc_f2fs, rc_full;
|
int rc_ext4, rc_f2fs, rc_full;
|
||||||
|
LOG(DEBUG) << "cryptfs_enable_inplace(" << crypto_blkdev << ", " << real_blkdev << ", " << size
|
||||||
|
<< ", " << size_already_done << ", " << tot_size << ", " << previously_encrypted_upto
|
||||||
|
<< ", " << set_progress_properties << ")";
|
||||||
if (previously_encrypted_upto) {
|
if (previously_encrypted_upto) {
|
||||||
LOG(DEBUG) << "Continuing encryption from " << previously_encrypted_upto;
|
LOG(DEBUG) << "Continuing encryption from " << previously_encrypted_upto;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*size_already_done + size < previously_encrypted_upto) {
|
if (*size_already_done + size < previously_encrypted_upto) {
|
||||||
|
LOG(DEBUG) << "cryptfs_enable_inplace already done";
|
||||||
*size_already_done += size;
|
*size_already_done += size;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -590,30 +604,33 @@ int cryptfs_enable_inplace(char* crypto_blkdev, char* real_blkdev, off64_t size,
|
||||||
* As is, cryptfs_enable_inplace_ext4 will fail on an f2fs partition, and
|
* As is, cryptfs_enable_inplace_ext4 will fail on an f2fs partition, and
|
||||||
* then we will drop down to cryptfs_enable_inplace_f2fs.
|
* then we will drop down to cryptfs_enable_inplace_f2fs.
|
||||||
* */
|
* */
|
||||||
if ((rc_ext4 = cryptfs_enable_inplace_ext4(crypto_blkdev, real_blkdev,
|
if ((rc_ext4 = cryptfs_enable_inplace_ext4(crypto_blkdev, real_blkdev, size, size_already_done,
|
||||||
size, size_already_done,
|
tot_size, previously_encrypted_upto,
|
||||||
tot_size, previously_encrypted_upto)) == 0) {
|
set_progress_properties)) == 0) {
|
||||||
return 0;
|
LOG(DEBUG) << "cryptfs_enable_inplace_ext4 success";
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
LOG(DEBUG) << "cryptfs_enable_inplace_ext4()=" << rc_ext4;
|
LOG(DEBUG) << "cryptfs_enable_inplace_ext4()=" << rc_ext4;
|
||||||
|
|
||||||
if ((rc_f2fs = cryptfs_enable_inplace_f2fs(crypto_blkdev, real_blkdev,
|
if ((rc_f2fs = cryptfs_enable_inplace_f2fs(crypto_blkdev, real_blkdev, size, size_already_done,
|
||||||
size, size_already_done,
|
tot_size, previously_encrypted_upto,
|
||||||
tot_size, previously_encrypted_upto)) == 0) {
|
set_progress_properties)) == 0) {
|
||||||
return 0;
|
LOG(DEBUG) << "cryptfs_enable_inplace_f2fs success";
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
LOG(DEBUG) << "cryptfs_enable_inplace_f2fs()=" << rc_f2fs;
|
LOG(DEBUG) << "cryptfs_enable_inplace_f2fs()=" << rc_f2fs;
|
||||||
|
|
||||||
rc_full = cryptfs_enable_inplace_full(crypto_blkdev, real_blkdev,
|
rc_full =
|
||||||
size, size_already_done, tot_size,
|
cryptfs_enable_inplace_full(crypto_blkdev, real_blkdev, size, size_already_done, tot_size,
|
||||||
previously_encrypted_upto);
|
previously_encrypted_upto, set_progress_properties);
|
||||||
LOG(DEBUG) << "cryptfs_enable_inplace_full()=" << rc_full;
|
LOG(DEBUG) << "cryptfs_enable_inplace_full()=" << rc_full;
|
||||||
|
|
||||||
/* Hack for b/17898962, the following is the symptom... */
|
/* Hack for b/17898962, the following is the symptom... */
|
||||||
if (rc_ext4 == ENABLE_INPLACE_ERR_DEV
|
if (rc_ext4 == ENABLE_INPLACE_ERR_DEV
|
||||||
&& rc_f2fs == ENABLE_INPLACE_ERR_DEV
|
&& rc_f2fs == ENABLE_INPLACE_ERR_DEV
|
||||||
&& rc_full == ENABLE_INPLACE_ERR_DEV) {
|
&& rc_full == ENABLE_INPLACE_ERR_DEV) {
|
||||||
return ENABLE_INPLACE_ERR_DEV;
|
LOG(DEBUG) << "ENABLE_INPLACE_ERR_DEV";
|
||||||
|
return ENABLE_INPLACE_ERR_DEV;
|
||||||
}
|
}
|
||||||
return rc_full;
|
return rc_full;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,9 +24,8 @@
|
||||||
#define RETRY_MOUNT_ATTEMPTS 10
|
#define RETRY_MOUNT_ATTEMPTS 10
|
||||||
#define RETRY_MOUNT_DELAY_SECONDS 1
|
#define RETRY_MOUNT_DELAY_SECONDS 1
|
||||||
|
|
||||||
int cryptfs_enable_inplace(char *crypto_blkdev, char *real_blkdev,
|
int cryptfs_enable_inplace(char* crypto_blkdev, char* real_blkdev, off64_t size,
|
||||||
off64_t size, off64_t *size_already_done,
|
off64_t* size_already_done, off64_t tot_size,
|
||||||
off64_t tot_size,
|
off64_t previously_encrypted_upto, bool set_progress_properties);
|
||||||
off64_t previously_encrypted_upto);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,8 +31,9 @@
|
||||||
#include <linux/dm-ioctl.h>
|
#include <linux/dm-ioctl.h>
|
||||||
|
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
|
#include <android-base/properties.h>
|
||||||
#include <android-base/unique_fd.h>
|
#include <android-base/unique_fd.h>
|
||||||
#include <cutils/properties.h>
|
#include <cutils/fs.h>
|
||||||
#include <fs_mgr.h>
|
#include <fs_mgr.h>
|
||||||
|
|
||||||
#include "EncryptInplace.h"
|
#include "EncryptInplace.h"
|
||||||
|
@ -71,26 +72,17 @@ static bool mount_via_fs_mgr(const char* mount_point, const char* blk_device) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool read_key(bool create_if_absent, KeyBuffer* key) {
|
static bool read_key(struct fstab_rec const* data_rec, bool create_if_absent, KeyBuffer* key) {
|
||||||
auto data_rec = fs_mgr_get_crypt_entry(fstab_default);
|
|
||||||
if (!data_rec) {
|
|
||||||
LOG(ERROR) << "Failed to get data_rec";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!data_rec->key_dir) {
|
if (!data_rec->key_dir) {
|
||||||
LOG(ERROR) << "Failed to get key_dir";
|
LOG(ERROR) << "Failed to get key_dir";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
LOG(DEBUG) << "key_dir: " << data_rec->key_dir;
|
|
||||||
if (!android::vold::pathExists(data_rec->key_dir)) {
|
|
||||||
if (mkdir(data_rec->key_dir, 0777) != 0) {
|
|
||||||
PLOG(ERROR) << "Unable to create: " << data_rec->key_dir;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
LOG(DEBUG) << "Created: " << data_rec->key_dir;
|
|
||||||
}
|
|
||||||
std::string key_dir = data_rec->key_dir;
|
std::string key_dir = data_rec->key_dir;
|
||||||
auto dir = key_dir + "/key";
|
auto dir = key_dir + "/key";
|
||||||
|
LOG(DEBUG) << "key_dir/key: " << key;
|
||||||
|
if (!fs_mkdirs(dir.c_str(), 0700)) {
|
||||||
|
PLOG(ERROR) << "Creating directories: " << dir;
|
||||||
|
}
|
||||||
auto temp = key_dir + "/tmp";
|
auto temp = key_dir + "/tmp";
|
||||||
if (!android::vold::retrieveKey(create_if_absent, dir, temp, key)) return false;
|
if (!android::vold::retrieveKey(create_if_absent, dir, temp, key)) return false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -103,7 +95,6 @@ static KeyBuffer default_key_params(const std::string& real_blkdev, const KeyBuf
|
||||||
return KeyBuffer();
|
return KeyBuffer();
|
||||||
}
|
}
|
||||||
auto res = KeyBuffer() + "AES-256-XTS " + hex_key + " " + real_blkdev.c_str() + " 0";
|
auto res = KeyBuffer() + "AES-256-XTS " + hex_key + " " + real_blkdev.c_str() + " 0";
|
||||||
LOG(DEBUG) << "crypt_params: " << std::string(res.data(), res.size());
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,108 +202,45 @@ static bool create_crypto_blk_dev(const std::string& dm_name, uint64_t nr_sec,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DATA_PREP_TIMEOUT 1000
|
bool e4crypt_mount_metadata_encrypted(const std::string& mount_point, bool needs_encrypt) {
|
||||||
static bool prep_data_fs(void)
|
LOG(DEBUG) << "e4crypt_mount_metadata_encrypted: " << mount_point << " " << needs_encrypt;
|
||||||
{
|
auto encrypted_state = android::base::GetProperty("ro.crypto.state", "");
|
||||||
// NOTE: post_fs_data results in init calling back around to vold, so all
|
if (encrypted_state != "") {
|
||||||
// callers to this method must be async
|
|
||||||
|
|
||||||
/* Do the prep of the /data filesystem */
|
|
||||||
property_set("vold.post_fs_data_done", "0");
|
|
||||||
property_set("vold.decrypt", "trigger_post_fs_data");
|
|
||||||
LOG(DEBUG) << "Waiting for post_fs_data_done";
|
|
||||||
|
|
||||||
/* Wait a max of 50 seconds, hopefully it takes much less */
|
|
||||||
for (int i = 0; ; i++) {
|
|
||||||
char p[PROPERTY_VALUE_MAX];
|
|
||||||
|
|
||||||
property_get("vold.post_fs_data_done", p, "0");
|
|
||||||
if (*p == '1') {
|
|
||||||
LOG(INFO) << "Successful data prep";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (i + 1 == DATA_PREP_TIMEOUT) {
|
|
||||||
LOG(ERROR) << "post_fs_data timed out";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
usleep(50000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void async_kick_off() {
|
|
||||||
LOG(DEBUG) << "Asynchronously restarting framework";
|
|
||||||
sleep(2); // TODO: this mirrors cryptfs, but can it be made shorter?
|
|
||||||
property_set("vold.decrypt", "trigger_load_persist_props");
|
|
||||||
if (!prep_data_fs()) return;
|
|
||||||
/* startup service classes main and late_start */
|
|
||||||
property_set("vold.decrypt", "trigger_restart_framework");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool e4crypt_mount_metadata_encrypted() {
|
|
||||||
LOG(DEBUG) << "e4crypt_mount_default_encrypted";
|
|
||||||
KeyBuffer key;
|
|
||||||
if (!read_key(false, &key)) return false;
|
|
||||||
auto data_rec = fs_mgr_get_crypt_entry(fstab_default);
|
|
||||||
if (!data_rec) {
|
|
||||||
LOG(ERROR) << "Failed to get data_rec";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
uint64_t nr_sec;
|
|
||||||
if (!get_number_of_sectors(data_rec->blk_device, &nr_sec)) return false;
|
|
||||||
std::string crypto_blkdev;
|
|
||||||
if (!create_crypto_blk_dev(kDmNameUserdata, nr_sec, DEFAULT_KEY_TARGET_TYPE,
|
|
||||||
default_key_params(data_rec->blk_device, key), &crypto_blkdev)) return false;
|
|
||||||
// FIXME handle the corrupt case
|
|
||||||
|
|
||||||
LOG(DEBUG) << "Restarting filesystem for metadata encryption";
|
|
||||||
mount_via_fs_mgr(data_rec->mount_point, crypto_blkdev.c_str());
|
|
||||||
std::thread(&async_kick_off).detach();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool e4crypt_enable_crypto() {
|
|
||||||
LOG(DEBUG) << "e4crypt_enable_crypto";
|
|
||||||
char encrypted_state[PROPERTY_VALUE_MAX];
|
|
||||||
property_get("ro.crypto.state", encrypted_state, "");
|
|
||||||
if (strcmp(encrypted_state, "")) {
|
|
||||||
LOG(DEBUG) << "e4crypt_enable_crypto got unexpected starting state: " << encrypted_state;
|
LOG(DEBUG) << "e4crypt_enable_crypto got unexpected starting state: " << encrypted_state;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
auto data_rec = fs_mgr_get_entry_for_mount_point(fstab_default, mount_point);
|
||||||
KeyBuffer key_ref;
|
|
||||||
if (!read_key(true, &key_ref)) return false;
|
|
||||||
|
|
||||||
auto data_rec = fs_mgr_get_crypt_entry(fstab_default);
|
|
||||||
if (!data_rec) {
|
if (!data_rec) {
|
||||||
LOG(ERROR) << "Failed to get data_rec";
|
LOG(ERROR) << "Failed to get data_rec";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
KeyBuffer key;
|
||||||
|
if (!read_key(data_rec, needs_encrypt, &key)) return false;
|
||||||
uint64_t nr_sec;
|
uint64_t nr_sec;
|
||||||
if (!get_number_of_sectors(data_rec->blk_device, &nr_sec)) return false;
|
if (!get_number_of_sectors(data_rec->blk_device, &nr_sec)) return false;
|
||||||
|
|
||||||
std::string crypto_blkdev;
|
std::string crypto_blkdev;
|
||||||
if (!create_crypto_blk_dev(kDmNameUserdata, nr_sec, DEFAULT_KEY_TARGET_TYPE,
|
if (!create_crypto_blk_dev(kDmNameUserdata, nr_sec, DEFAULT_KEY_TARGET_TYPE,
|
||||||
default_key_params(data_rec->blk_device, key_ref), &crypto_blkdev)) return false;
|
default_key_params(data_rec->blk_device, key), &crypto_blkdev))
|
||||||
|
|
||||||
LOG(INFO) << "Beginning inplace encryption, nr_sec: " << nr_sec;
|
|
||||||
off64_t size_already_done = 0;
|
|
||||||
auto rc = cryptfs_enable_inplace(const_cast<char *>(crypto_blkdev.c_str()),
|
|
||||||
data_rec->blk_device, nr_sec, &size_already_done, nr_sec, 0);
|
|
||||||
if (rc != 0) {
|
|
||||||
LOG(ERROR) << "Inplace crypto failed with code: " << rc;
|
|
||||||
return false;
|
return false;
|
||||||
|
// FIXME handle the corrupt case
|
||||||
|
if (needs_encrypt) {
|
||||||
|
LOG(INFO) << "Beginning inplace encryption, nr_sec: " << nr_sec;
|
||||||
|
off64_t size_already_done = 0;
|
||||||
|
auto rc =
|
||||||
|
cryptfs_enable_inplace(const_cast<char*>(crypto_blkdev.c_str()), data_rec->blk_device,
|
||||||
|
nr_sec, &size_already_done, nr_sec, 0, false);
|
||||||
|
if (rc != 0) {
|
||||||
|
LOG(ERROR) << "Inplace crypto failed with code: " << rc;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (static_cast<uint64_t>(size_already_done) != nr_sec) {
|
||||||
|
LOG(ERROR) << "Inplace crypto only got up to sector: " << size_already_done;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LOG(INFO) << "Inplace encryption complete";
|
||||||
}
|
}
|
||||||
if (static_cast<uint64_t>(size_already_done) != nr_sec) {
|
|
||||||
LOG(ERROR) << "Inplace crypto only got up to sector: " << size_already_done;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
LOG(INFO) << "Inplace encryption complete";
|
|
||||||
|
|
||||||
property_set("ro.crypto.state", "encrypted");
|
|
||||||
property_set("ro.crypto.type", "file");
|
|
||||||
|
|
||||||
|
LOG(DEBUG) << "Mounting metadata-encrypted filesystem:" << mount_point;
|
||||||
mount_via_fs_mgr(data_rec->mount_point, crypto_blkdev.c_str());
|
mount_via_fs_mgr(data_rec->mount_point, crypto_blkdev.c_str());
|
||||||
property_set("vold.decrypt", "trigger_reset_main");
|
|
||||||
std::thread(&async_kick_off).detach();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
#ifndef _METADATA_CRYPT_H
|
#ifndef _METADATA_CRYPT_H
|
||||||
#define _METADATA_CRYPT_H
|
#define _METADATA_CRYPT_H
|
||||||
|
|
||||||
bool e4crypt_mount_metadata_encrypted();
|
#include <string>
|
||||||
bool e4crypt_enable_crypto();
|
|
||||||
|
bool e4crypt_mount_metadata_encrypted(const std::string& mount_point, bool needs_encrypt);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -247,16 +247,6 @@ binder::Status VoldNativeService::shutdown() {
|
||||||
return translate(VolumeManager::Instance()->shutdown());
|
return translate(VolumeManager::Instance()->shutdown());
|
||||||
}
|
}
|
||||||
|
|
||||||
binder::Status VoldNativeService::mountAll() {
|
|
||||||
ENFORCE_UID(AID_SYSTEM);
|
|
||||||
ACQUIRE_LOCK;
|
|
||||||
|
|
||||||
struct fstab* fstab = fs_mgr_read_fstab_default();
|
|
||||||
int res = fs_mgr_mount_all(fstab, MOUNT_MODE_DEFAULT);
|
|
||||||
fs_mgr_free_fstab(fstab);
|
|
||||||
return translate(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
binder::Status VoldNativeService::onUserAdded(int32_t userId, int32_t userSerial) {
|
binder::Status VoldNativeService::onUserAdded(int32_t userId, int32_t userSerial) {
|
||||||
ENFORCE_UID(AID_SYSTEM);
|
ENFORCE_UID(AID_SYSTEM);
|
||||||
ACQUIRE_LOCK;
|
ACQUIRE_LOCK;
|
||||||
|
@ -577,12 +567,12 @@ binder::Status VoldNativeService::fdeEnable(int32_t passwordType,
|
||||||
ENFORCE_UID(AID_SYSTEM);
|
ENFORCE_UID(AID_SYSTEM);
|
||||||
ACQUIRE_CRYPT_LOCK;
|
ACQUIRE_CRYPT_LOCK;
|
||||||
|
|
||||||
|
LOG(DEBUG) << "fdeEnable(" << passwordType << ", *, " << encryptionFlags << ")";
|
||||||
if (e4crypt_is_native()) {
|
if (e4crypt_is_native()) {
|
||||||
if (passwordType != PASSWORD_TYPE_DEFAULT) {
|
LOG(ERROR) << "e4crypt_is_native, fdeEnable invalid";
|
||||||
return error("Unexpected password type");
|
return error("e4crypt_is_native, fdeEnable invalid");
|
||||||
}
|
|
||||||
return translateBool(e4crypt_enable_crypto());
|
|
||||||
}
|
}
|
||||||
|
LOG(DEBUG) << "!e4crypt_is_native, spawning fdeEnableInternal";
|
||||||
|
|
||||||
// Spawn as thread so init can issue commands back to vold without
|
// Spawn as thread so init can issue commands back to vold without
|
||||||
// causing deadlock, usually as a result of prep_data_fs.
|
// causing deadlock, usually as a result of prep_data_fs.
|
||||||
|
@ -665,14 +655,12 @@ binder::Status VoldNativeService::mountDefaultEncrypted() {
|
||||||
ENFORCE_UID(AID_SYSTEM);
|
ENFORCE_UID(AID_SYSTEM);
|
||||||
ACQUIRE_CRYPT_LOCK;
|
ACQUIRE_CRYPT_LOCK;
|
||||||
|
|
||||||
if (e4crypt_is_native()) {
|
if (!e4crypt_is_native()) {
|
||||||
return translateBool(e4crypt_mount_metadata_encrypted());
|
|
||||||
} else {
|
|
||||||
// Spawn as thread so init can issue commands back to vold without
|
// Spawn as thread so init can issue commands back to vold without
|
||||||
// causing deadlock, usually as a result of prep_data_fs.
|
// causing deadlock, usually as a result of prep_data_fs.
|
||||||
std::thread(&cryptfs_mount_default_encrypted).detach();
|
std::thread(&cryptfs_mount_default_encrypted).detach();
|
||||||
return ok();
|
|
||||||
}
|
}
|
||||||
|
return ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
binder::Status VoldNativeService::initUser0() {
|
binder::Status VoldNativeService::initUser0() {
|
||||||
|
@ -690,6 +678,20 @@ binder::Status VoldNativeService::isConvertibleToFbe(bool* _aidl_return) {
|
||||||
return ok();
|
return ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binder::Status VoldNativeService::mountFstab(const std::string& mountPoint) {
|
||||||
|
ENFORCE_UID(AID_SYSTEM);
|
||||||
|
ACQUIRE_LOCK;
|
||||||
|
|
||||||
|
return translateBool(e4crypt_mount_metadata_encrypted(mountPoint, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
binder::Status VoldNativeService::encryptFstab(const std::string& mountPoint) {
|
||||||
|
ENFORCE_UID(AID_SYSTEM);
|
||||||
|
ACQUIRE_LOCK;
|
||||||
|
|
||||||
|
return translateBool(e4crypt_mount_metadata_encrypted(mountPoint, true));
|
||||||
|
}
|
||||||
|
|
||||||
binder::Status VoldNativeService::createUserKey(int32_t userId, int32_t userSerial,
|
binder::Status VoldNativeService::createUserKey(int32_t userId, int32_t userSerial,
|
||||||
bool ephemeral) {
|
bool ephemeral) {
|
||||||
ENFORCE_UID(AID_SYSTEM);
|
ENFORCE_UID(AID_SYSTEM);
|
||||||
|
|
|
@ -36,7 +36,6 @@ public:
|
||||||
binder::Status monitor();
|
binder::Status monitor();
|
||||||
binder::Status reset();
|
binder::Status reset();
|
||||||
binder::Status shutdown();
|
binder::Status shutdown();
|
||||||
binder::Status mountAll();
|
|
||||||
|
|
||||||
binder::Status onUserAdded(int32_t userId, int32_t userSerial);
|
binder::Status onUserAdded(int32_t userId, int32_t userSerial);
|
||||||
binder::Status onUserRemoved(int32_t userId);
|
binder::Status onUserRemoved(int32_t userId);
|
||||||
|
@ -96,6 +95,8 @@ public:
|
||||||
binder::Status mountDefaultEncrypted();
|
binder::Status mountDefaultEncrypted();
|
||||||
binder::Status initUser0();
|
binder::Status initUser0();
|
||||||
binder::Status isConvertibleToFbe(bool* _aidl_return);
|
binder::Status isConvertibleToFbe(bool* _aidl_return);
|
||||||
|
binder::Status mountFstab(const std::string& mountPoint);
|
||||||
|
binder::Status encryptFstab(const std::string& mountPoint);
|
||||||
|
|
||||||
binder::Status createUserKey(int32_t userId, int32_t userSerial, bool ephemeral);
|
binder::Status createUserKey(int32_t userId, int32_t userSerial, bool ephemeral);
|
||||||
binder::Status destroyUserKey(int32_t userId);
|
binder::Status destroyUserKey(int32_t userId);
|
||||||
|
|
|
@ -26,7 +26,6 @@ interface IVold {
|
||||||
void monitor();
|
void monitor();
|
||||||
void reset();
|
void reset();
|
||||||
void shutdown();
|
void shutdown();
|
||||||
void mountAll();
|
|
||||||
|
|
||||||
void onUserAdded(int userId, int userSerial);
|
void onUserAdded(int userId, int userSerial);
|
||||||
void onUserRemoved(int userId);
|
void onUserRemoved(int userId);
|
||||||
|
@ -79,6 +78,8 @@ interface IVold {
|
||||||
void mountDefaultEncrypted();
|
void mountDefaultEncrypted();
|
||||||
void initUser0();
|
void initUser0();
|
||||||
boolean isConvertibleToFbe();
|
boolean isConvertibleToFbe();
|
||||||
|
void mountFstab(@utf8InCpp String mountPoint);
|
||||||
|
void encryptFstab(@utf8InCpp String mountPoint);
|
||||||
|
|
||||||
void createUserKey(int userId, int userSerial, boolean ephemeral);
|
void createUserKey(int userId, int userSerial, boolean ephemeral);
|
||||||
void destroyUserKey(int userId);
|
void destroyUserKey(int userId);
|
||||||
|
|
|
@ -1974,7 +1974,7 @@ static int cryptfs_enable_all_volumes(struct crypt_mnt_ftr* crypt_ftr, char* cry
|
||||||
tot_encryption_size = crypt_ftr->fs_size;
|
tot_encryption_size = crypt_ftr->fs_size;
|
||||||
|
|
||||||
rc = cryptfs_enable_inplace(crypto_blkdev, real_blkdev, crypt_ftr->fs_size, &cur_encryption_done,
|
rc = cryptfs_enable_inplace(crypto_blkdev, real_blkdev, crypt_ftr->fs_size, &cur_encryption_done,
|
||||||
tot_encryption_size, previously_encrypted_upto);
|
tot_encryption_size, previously_encrypted_upto, true);
|
||||||
|
|
||||||
if (rc == ENABLE_INPLACE_ERR_DEV) {
|
if (rc == ENABLE_INPLACE_ERR_DEV) {
|
||||||
/* Hack for b/17898962 */
|
/* Hack for b/17898962 */
|
||||||
|
|
6
main.cpp
6
main.cpp
|
@ -51,12 +51,14 @@ struct selabel_handle *sehandle;
|
||||||
using android::base::StringPrintf;
|
using android::base::StringPrintf;
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
atrace_set_tracing_enabled(false);
|
||||||
setenv("ANDROID_LOG_TAGS", "*:v", 1);
|
setenv("ANDROID_LOG_TAGS", "*:v", 1);
|
||||||
android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
|
android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
|
||||||
|
|
||||||
|
LOG(INFO) << "Vold 3.0 (the awakening) firing up";
|
||||||
|
|
||||||
ATRACE_BEGIN("main");
|
ATRACE_BEGIN("main");
|
||||||
|
|
||||||
LOG(INFO) << "Vold 3.0 (the awakening) firing up";
|
|
||||||
|
|
||||||
LOG(VERBOSE) << "Detected support for:"
|
LOG(VERBOSE) << "Detected support for:"
|
||||||
<< (android::vold::IsFilesystemSupported("ext4") ? " ext4" : "")
|
<< (android::vold::IsFilesystemSupported("ext4") ? " ext4" : "")
|
||||||
|
@ -113,6 +115,8 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
ATRACE_END();
|
ATRACE_END();
|
||||||
|
|
||||||
|
LOG(DEBUG) << "VoldNativeService::start() completed OK";
|
||||||
|
|
||||||
ATRACE_BEGIN("NetlinkManager::start");
|
ATRACE_BEGIN("NetlinkManager::start");
|
||||||
if (nm->start()) {
|
if (nm->start()) {
|
||||||
PLOG(ERROR) << "Unable to start NetlinkManager";
|
PLOG(ERROR) << "Unable to start NetlinkManager";
|
||||||
|
|
6
vdc.cpp
6
vdc.cpp
|
@ -44,7 +44,7 @@ static android::sp<android::IBinder> getServiceAggressive() {
|
||||||
android::sp<android::IBinder> res;
|
android::sp<android::IBinder> res;
|
||||||
auto sm = android::defaultServiceManager();
|
auto sm = android::defaultServiceManager();
|
||||||
auto name = android::String16("vold");
|
auto name = android::String16("vold");
|
||||||
for (int i = 0; i < 500; i++) {
|
for (int i = 0; i < 5000; i++) {
|
||||||
res = sm->checkService(name);
|
res = sm->checkService(name);
|
||||||
if (res) {
|
if (res) {
|
||||||
LOG(VERBOSE) << "Waited " << (i * 10) << "ms for vold";
|
LOG(VERBOSE) << "Waited " << (i * 10) << "ms for vold";
|
||||||
|
@ -101,6 +101,10 @@ int main(int argc, char** argv) {
|
||||||
checkStatus(vold->shutdown());
|
checkStatus(vold->shutdown());
|
||||||
} else if (args[0] == "cryptfs" && args[1] == "checkEncryption" && args.size() == 3) {
|
} else if (args[0] == "cryptfs" && args[1] == "checkEncryption" && args.size() == 3) {
|
||||||
checkStatus(vold->checkEncryption(args[2]));
|
checkStatus(vold->checkEncryption(args[2]));
|
||||||
|
} else if (args[0] == "cryptfs" && args[1] == "mountFstab" && args.size() == 3) {
|
||||||
|
checkStatus(vold->mountFstab(args[2]));
|
||||||
|
} else if (args[0] == "cryptfs" && args[1] == "encryptFstab" && args.size() == 3) {
|
||||||
|
checkStatus(vold->encryptFstab(args[2]));
|
||||||
} else {
|
} else {
|
||||||
LOG(ERROR) << "Raw commands are no longer supported";
|
LOG(ERROR) << "Raw commands are no longer supported";
|
||||||
exit(EINVAL);
|
exit(EINVAL);
|
||||||
|
|
Loading…
Reference in a new issue