Merge QP1A.181119.002
Change-Id: I1abb62e2234f8cf86116270d67e5051a57b6d72f
diff --git a/Android.bp b/Android.bp
index d4fff02..929bbcb 100644
--- a/Android.bp
+++ b/Android.bp
@@ -48,6 +48,7 @@
"libdiskconfig",
"libext4_utils",
"libf2fs_sparseblock",
+ "libfscrypt",
"libhardware",
"libhardware_legacy",
"libhidlbase",
@@ -99,8 +100,8 @@
"Checkpoint.cpp",
"Devmapper.cpp",
"EncryptInplace.cpp",
- "Ext4Crypt.cpp",
"FileDeviceUtils.cpp",
+ "FsCrypt.cpp",
"IdleMaint.cpp",
"KeyBuffer.cpp",
"KeyStorage.cpp",
@@ -128,6 +129,7 @@
"model/PrivateVolume.cpp",
"model/PublicVolume.cpp",
"model/VolumeBase.cpp",
+ "model/StubVolume.cpp",
"secontext.cpp",
],
product_variables: {
diff --git a/Ext4Crypt.cpp b/FsCrypt.cpp
similarity index 91%
rename from Ext4Crypt.cpp
rename to FsCrypt.cpp
index 5398b79..6fd611c 100644
--- a/Ext4Crypt.cpp
+++ b/FsCrypt.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "Ext4Crypt.h"
+#include "FsCrypt.h"
#include "Keymaster.h"
#include "KeyStorage.h"
@@ -51,13 +51,14 @@
#include <cutils/fs.h>
#include <cutils/properties.h>
-#include <ext4_utils/ext4_crypt.h>
+#include <fscrypt/fscrypt.h>
#include <keyutils.h>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
using android::base::StringPrintf;
using android::base::WriteStringToFile;
@@ -74,7 +75,7 @@
std::string key_raw_ref;
};
-const std::string device_key_dir = std::string() + DATA_MNT_POINT + e4crypt_unencrypted_folder;
+const std::string device_key_dir = std::string() + DATA_MNT_POINT + fscrypt_unencrypted_folder;
const std::string device_key_path = device_key_dir + "/key";
const std::string device_key_temp = device_key_dir + "/temp";
@@ -98,7 +99,7 @@
} // namespace
-static bool e4crypt_is_emulated() {
+static bool fscrypt_is_emulated() {
return property_get_bool("persist.sys.emulate_fbe", false);
}
@@ -175,8 +176,25 @@
auto const current_path = get_ce_key_current_path(directory_path);
if (to_fix != current_path) {
LOG(DEBUG) << "Renaming " << to_fix << " to " << current_path;
+ android::base::unique_fd fd(TEMP_FAILURE_RETRY(
+ open(to_fix.c_str(), O_RDONLY | O_CLOEXEC)));
+ if (fd == -1) {
+ PLOG(ERROR) << "Failed to open " << to_fix;
+ return;
+ }
+ if (fsync(fd) == -1) {
+ if (errno == EROFS || errno == EINVAL) {
+ PLOG(WARNING) << "Skip fsync " << to_fix
+ << " on a file system does not support synchronization";
+ } else {
+ PLOG(ERROR) << "Failed to fsync " << to_fix;
+ unlink(to_fix.c_str());
+ return;
+ }
+ }
if (rename(to_fix.c_str(), current_path.c_str()) != 0) {
PLOG(WARNING) << "Unable to rename " << to_fix << " to " << current_path;
+ return;
}
}
}
@@ -333,7 +351,7 @@
}
static bool ensure_policy(const PolicyKeyRef& key_ref, const std::string& path) {
- return e4crypt_policy_ensure(path.c_str(), key_ref.key_raw_ref.data(),
+ return fscrypt_policy_ensure(path.c_str(), key_ref.key_raw_ref.data(),
key_ref.key_raw_ref.size(), key_ref.contents_mode.c_str(),
key_ref.filenames_mode.c_str()) == 0;
}
@@ -385,13 +403,13 @@
LOG(DEBUG) << "Installed de key for user " << user_id;
}
}
- // ext4enc:TODO: go through all DE directories, ensure that all user dirs have the
+ // fscrypt:TODO: go through all DE directories, ensure that all user dirs have the
// correct policy set on them, and that no rogue ones exist.
return true;
}
-bool e4crypt_initialize_global_de() {
- LOG(INFO) << "e4crypt_initialize_global_de";
+bool fscrypt_initialize_global_de() {
+ LOG(INFO) << "fscrypt_initialize_global_de";
bool wrapped_key_supported = false;
if (s_global_de_initialized) {
@@ -409,13 +427,13 @@
get_data_file_encryption_modes(&device_ref);
std::string modestring = device_ref.contents_mode + ":" + device_ref.filenames_mode;
- std::string mode_filename = std::string("/data") + e4crypt_key_mode;
+ std::string mode_filename = std::string("/data") + fscrypt_key_mode;
if (!android::base::WriteStringToFile(modestring, mode_filename)) {
PLOG(ERROR) << "Cannot save type";
return false;
}
- std::string ref_filename = std::string("/data") + e4crypt_key_ref;
+ std::string ref_filename = std::string("/data") + fscrypt_key_ref;
if (!android::base::WriteStringToFile(device_ref.key_raw_ref, ref_filename)) {
PLOG(ERROR) << "Cannot save key reference to:" << ref_filename;
return false;
@@ -426,9 +444,9 @@
return true;
}
-bool e4crypt_init_user0() {
- LOG(DEBUG) << "e4crypt_init_user0";
- if (e4crypt_is_native()) {
+bool fscrypt_init_user0() {
+ LOG(DEBUG) << "fscrypt_init_user0";
+ if (fscrypt_is_native()) {
if (!prepare_dir(user_key_dir, 0700, AID_ROOT, AID_ROOT)) return false;
if (!prepare_dir(user_key_dir + "/ce", 0700, AID_ROOT, AID_ROOT)) return false;
if (!prepare_dir(user_key_dir + "/de", 0700, AID_ROOT, AID_ROOT)) return false;
@@ -442,28 +460,28 @@
// We can only safely prepare DE storage here, since CE keys are probably
// entangled with user credentials. The framework will always prepare CE
// storage once CE keys are installed.
- if (!e4crypt_prepare_user_storage("", 0, 0, android::os::IVold::STORAGE_FLAG_DE)) {
+ if (!fscrypt_prepare_user_storage("", 0, 0, android::os::IVold::STORAGE_FLAG_DE)) {
LOG(ERROR) << "Failed to prepare user 0 storage";
return false;
}
// If this is a non-FBE device that recently left an emulated mode,
// restore user data directories to known-good state.
- if (!e4crypt_is_native() && !e4crypt_is_emulated()) {
- e4crypt_unlock_user_key(0, 0, "!", "!");
+ if (!fscrypt_is_native() && !fscrypt_is_emulated()) {
+ fscrypt_unlock_user_key(0, 0, "!", "!");
}
return true;
}
-bool e4crypt_vold_create_user_key(userid_t user_id, int serial, bool ephemeral) {
- LOG(DEBUG) << "e4crypt_vold_create_user_key for " << user_id << " serial " << serial;
- if (!e4crypt_is_native()) {
+bool fscrypt_vold_create_user_key(userid_t user_id, int serial, bool ephemeral) {
+ LOG(DEBUG) << "fscrypt_vold_create_user_key for " << user_id << " serial " << serial;
+ if (!fscrypt_is_native()) {
return true;
}
// FIXME test for existence of key that is not loaded yet
if (s_ce_key_raw_refs.count(user_id) != 0) {
- LOG(ERROR) << "Already exists, can't e4crypt_vold_create_user_key for " << user_id
+ LOG(ERROR) << "Already exists, can't fscrypt_vold_create_user_key for " << user_id
<< " serial " << serial;
// FIXME should we fail the command?
return true;
@@ -496,9 +514,9 @@
return success;
}
-bool e4crypt_destroy_user_key(userid_t user_id) {
- LOG(DEBUG) << "e4crypt_destroy_user_key(" << user_id << ")";
- if (!e4crypt_is_native()) {
+bool fscrypt_destroy_user_key(userid_t user_id) {
+ LOG(DEBUG) << "fscrypt_destroy_user_key(" << user_id << ")";
+ if (!fscrypt_is_native()) {
return true;
}
bool success = true;
@@ -542,13 +560,13 @@
if (chmod(path.c_str(), mode) != 0) {
PLOG(ERROR) << "Failed to chmod " << path;
// FIXME temporary workaround for b/26713622
- if (e4crypt_is_emulated()) return false;
+ if (fscrypt_is_emulated()) return false;
}
#if EMULATED_USES_SELINUX
if (selinux_android_restorecon(path.c_str(), SELINUX_ANDROID_RESTORECON_FORCE) != 0) {
PLOG(WARNING) << "Failed to restorecon " << path;
// FIXME temporary workaround for b/26713622
- if (e4crypt_is_emulated()) return false;
+ if (fscrypt_is_emulated()) return false;
}
#endif
return true;
@@ -614,11 +632,11 @@
return android::vold::destroyKey(path);
}
-bool e4crypt_add_user_key_auth(userid_t user_id, int serial, const std::string& token_hex,
+bool fscrypt_add_user_key_auth(userid_t user_id, int serial, const std::string& token_hex,
const std::string& secret_hex) {
- LOG(DEBUG) << "e4crypt_add_user_key_auth " << user_id << " serial=" << serial
+ LOG(DEBUG) << "fscrypt_add_user_key_auth " << user_id << " serial=" << serial
<< " token_present=" << (token_hex != "!");
- if (!e4crypt_is_native()) return true;
+ if (!fscrypt_is_native()) return true;
if (s_ephemeral_users.count(user_id) != 0) return true;
std::string token, secret;
if (!parse_hex(token_hex, &token)) return false;
@@ -653,11 +671,11 @@
return true;
}
-bool e4crypt_clear_user_key_auth(userid_t user_id, int serial, const std::string& token_hex,
+bool fscrypt_clear_user_key_auth(userid_t user_id, int serial, const std::string& token_hex,
const std::string& secret_hex) {
- LOG(DEBUG) << "e4crypt_clear_user_key_auth " << user_id << " serial=" << serial
+ LOG(DEBUG) << "fscrypt_clear_user_key_auth " << user_id << " serial=" << serial
<< " token_present=" << (token_hex != "!");
- if (!e4crypt_is_native()) return true;
+ if (!fscrypt_is_native()) return true;
if (s_ephemeral_users.count(user_id) != 0) return true;
std::string token, secret;
@@ -688,14 +706,14 @@
if (!android::vold::storeKeyAtomically(ce_key_path, user_key_temp, kEmptyAuthentication, ce_key))
return false;
} else {
- if(!e4crypt_add_user_key_auth(user_id, serial, "!", "!")) return false;
+ if(!fscrypt_add_user_key_auth(user_id, serial, "!", "!")) return false;
}
return true;
}
-bool e4crypt_fixate_newest_user_key_auth(userid_t user_id) {
- LOG(DEBUG) << "e4crypt_fixate_newest_user_key_auth " << user_id;
- if (!e4crypt_is_native()) return true;
+bool fscrypt_fixate_newest_user_key_auth(userid_t user_id) {
+ LOG(DEBUG) << "fscrypt_fixate_newest_user_key_auth " << user_id;
+ if (!fscrypt_is_native()) return true;
if (s_ephemeral_users.count(user_id) != 0) return true;
auto const directory_path = get_ce_key_directory_path(user_id);
auto const paths = get_ce_key_paths(directory_path);
@@ -708,11 +726,11 @@
}
// TODO: rename to 'install' for consistency, and take flags to know which keys to install
-bool e4crypt_unlock_user_key(userid_t user_id, int serial, const std::string& token_hex,
+bool fscrypt_unlock_user_key(userid_t user_id, int serial, const std::string& token_hex,
const std::string& secret_hex) {
- LOG(DEBUG) << "e4crypt_unlock_user_key " << user_id << " serial=" << serial
+ LOG(DEBUG) << "fscrypt_unlock_user_key " << user_id << " serial=" << serial
<< " token_present=" << (token_hex != "!");
- if (e4crypt_is_native()) {
+ if (fscrypt_is_native()) {
if (s_ce_key_raw_refs.count(user_id) != 0) {
LOG(WARNING) << "Tried to unlock already-unlocked key for user " << user_id;
return true;
@@ -741,11 +759,11 @@
}
// TODO: rename to 'evict' for consistency
-bool e4crypt_lock_user_key(userid_t user_id) {
- LOG(DEBUG) << "e4crypt_lock_user_key " << user_id;
- if (e4crypt_is_native()) {
+bool fscrypt_lock_user_key(userid_t user_id) {
+ LOG(DEBUG) << "fscrypt_lock_user_key " << user_id;
+ if (fscrypt_is_native()) {
return evict_ce_key(user_id);
- } else if (e4crypt_is_emulated()) {
+ } else if (fscrypt_is_emulated()) {
// When in emulation mode, we just use chmod
if (!emulated_lock(android::vold::BuildDataSystemCePath(user_id)) ||
!emulated_lock(android::vold::BuildDataMiscCePath(user_id)) ||
@@ -770,9 +788,9 @@
return true;
}
-bool e4crypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_id, int serial,
+bool fscrypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_id, int serial,
int flags) {
- LOG(DEBUG) << "e4crypt_prepare_user_storage for volume " << escape_empty(volume_uuid)
+ LOG(DEBUG) << "fscrypt_prepare_user_storage for volume " << escape_empty(volume_uuid)
<< ", user " << user_id << ", serial " << serial << ", flags " << flags;
if (flags & android::os::IVold::STORAGE_FLAG_DE) {
@@ -802,7 +820,7 @@
}
if (!prepare_dir(user_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
- if (e4crypt_is_native()) {
+ if (fscrypt_is_native()) {
PolicyKeyRef de_ref;
if (volume_uuid.empty()) {
if (!lookup_key_ref(s_de_key_raw_refs, user_id, &de_ref.key_raw_ref)) return false;
@@ -833,7 +851,7 @@
if (!prepare_dir(media_ce_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW)) return false;
if (!prepare_dir(user_ce_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
- if (e4crypt_is_native()) {
+ if (fscrypt_is_native()) {
PolicyKeyRef ce_ref;
if (volume_uuid.empty()) {
if (!lookup_key_ref(s_ce_key_raw_refs, user_id, &ce_ref.key_raw_ref)) return false;
@@ -862,8 +880,8 @@
return true;
}
-bool e4crypt_destroy_user_storage(const std::string& volume_uuid, userid_t user_id, int flags) {
- LOG(DEBUG) << "e4crypt_destroy_user_storage for volume " << escape_empty(volume_uuid)
+bool fscrypt_destroy_user_storage(const std::string& volume_uuid, userid_t user_id, int flags) {
+ LOG(DEBUG) << "fscrypt_destroy_user_storage for volume " << escape_empty(volume_uuid)
<< ", user " << user_id << ", flags " << flags;
bool res = true;
@@ -884,7 +902,7 @@
res &= destroy_dir(misc_ce_path);
res &= destroy_dir(vendor_ce_path);
} else {
- if (e4crypt_is_native()) {
+ if (fscrypt_is_native()) {
res &= destroy_volkey(misc_ce_path, volume_uuid);
}
}
@@ -913,7 +931,7 @@
res &= destroy_dir(misc_de_path);
res &= destroy_dir(vendor_de_path);
} else {
- if (e4crypt_is_native()) {
+ if (fscrypt_is_native()) {
res &= destroy_volkey(misc_de_path, volume_uuid);
}
}
@@ -948,9 +966,9 @@
return res;
}
-bool e4crypt_destroy_volume_keys(const std::string& volume_uuid) {
+bool fscrypt_destroy_volume_keys(const std::string& volume_uuid) {
bool res = true;
- LOG(DEBUG) << "e4crypt_destroy_volume_keys for volume " << escape_empty(volume_uuid);
+ LOG(DEBUG) << "fscrypt_destroy_volume_keys for volume " << escape_empty(volume_uuid);
auto secdiscardable_path = volume_secdiscardable_path(volume_uuid);
res &= android::vold::runSecdiscardSingle(secdiscardable_path);
res &= destroy_volume_keys("/data/misc_ce", volume_uuid);
diff --git a/Ext4Crypt.h b/FsCrypt.h
similarity index 63%
rename from Ext4Crypt.h
rename to FsCrypt.h
index 5101bf6..d81271c 100644
--- a/Ext4Crypt.h
+++ b/FsCrypt.h
@@ -18,25 +18,25 @@
#include <cutils/multiuser.h>
-bool e4crypt_initialize_global_de();
+bool fscrypt_initialize_global_de();
-bool e4crypt_init_user0();
-bool e4crypt_vold_create_user_key(userid_t user_id, int serial, bool ephemeral);
-bool e4crypt_destroy_user_key(userid_t user_id);
-bool e4crypt_add_user_key_auth(userid_t user_id, int serial, const std::string& token,
+bool fscrypt_init_user0();
+bool fscrypt_vold_create_user_key(userid_t user_id, int serial, bool ephemeral);
+bool fscrypt_destroy_user_key(userid_t user_id);
+bool fscrypt_add_user_key_auth(userid_t user_id, int serial, const std::string& token,
const std::string& secret);
-bool e4crypt_clear_user_key_auth(userid_t user_id, int serial, const std::string& token_hex,
+bool fscrypt_clear_user_key_auth(userid_t user_id, int serial, const std::string& token_hex,
const std::string& secret_hex);
-bool e4crypt_fixate_newest_user_key_auth(userid_t user_id);
+bool fscrypt_fixate_newest_user_key_auth(userid_t user_id);
-bool e4crypt_unlock_user_key(userid_t user_id, int serial, const std::string& token,
+bool fscrypt_unlock_user_key(userid_t user_id, int serial, const std::string& token,
const std::string& secret);
-bool e4crypt_lock_user_key(userid_t user_id);
+bool fscrypt_lock_user_key(userid_t user_id);
-bool e4crypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_id, int serial,
+bool fscrypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_id, int serial,
int flags);
-bool e4crypt_destroy_user_storage(const std::string& volume_uuid, userid_t user_id, int flags);
+bool fscrypt_destroy_user_storage(const std::string& volume_uuid, userid_t user_id, int flags);
-bool e4crypt_destroy_volume_keys(const std::string& volume_uuid);
+bool fscrypt_destroy_volume_keys(const std::string& volume_uuid);
bool is_wrapped_key_supported();
bool is_wrapped_key_supported_external();
diff --git a/KeyUtil.cpp b/KeyUtil.cpp
index 70a1952..cd2171b 100644
--- a/KeyUtil.cpp
+++ b/KeyUtil.cpp
@@ -16,6 +16,7 @@
#include "KeyUtil.h"
+#include <linux/fs.h>
#include <iomanip>
#include <sstream>
#include <string>
@@ -37,22 +38,10 @@
namespace android {
namespace vold {
-// ext4enc:TODO get this const from somewhere good
-const int EXT4_KEY_DESCRIPTOR_SIZE = 8;
-
-// ext4enc:TODO Include structure from somewhere sensible
-// MUST be in sync with ext4_crypto.c in kernel
-constexpr int EXT4_ENCRYPTION_MODE_AES_256_XTS = 1;
-constexpr int EXT4_AES_256_XTS_KEY_SIZE = 64;
-constexpr int EXT4_MAX_KEY_SIZE = 64;
-struct ext4_encryption_key {
- uint32_t mode;
- char raw[EXT4_MAX_KEY_SIZE];
- uint32_t size;
-};
+constexpr int FS_AES_256_XTS_KEY_SIZE = 64;
bool randomKey(KeyBuffer* key) {
- *key = KeyBuffer(EXT4_AES_256_XTS_KEY_SIZE);
+ *key = KeyBuffer(FS_AES_256_XTS_KEY_SIZE);
if (ReadRandomBytes(key->size(), key->data()) != 0) {
// TODO status_t plays badly with PLOG, fix it.
LOG(ERROR) << "Random read failed";
@@ -62,7 +51,7 @@
}
// Get raw keyref - used to make keyname and to pass to ioctl
-static std::string generateKeyRef(const char* key, int length) {
+static std::string generateKeyRef(const uint8_t* key, int length) {
SHA512_CTX c;
SHA512_Init(&c);
@@ -75,21 +64,20 @@
unsigned char key_ref2[SHA512_DIGEST_LENGTH];
SHA512_Final(key_ref2, &c);
- static_assert(EXT4_KEY_DESCRIPTOR_SIZE <= SHA512_DIGEST_LENGTH,
- "Hash too short for descriptor");
- return std::string((char*)key_ref2, EXT4_KEY_DESCRIPTOR_SIZE);
+ static_assert(FS_KEY_DESCRIPTOR_SIZE <= SHA512_DIGEST_LENGTH, "Hash too short for descriptor");
+ return std::string((char*)key_ref2, FS_KEY_DESCRIPTOR_SIZE);
}
-static bool fillKey(const KeyBuffer& key, ext4_encryption_key* ext4_key) {
- if (key.size() != EXT4_AES_256_XTS_KEY_SIZE) {
+static bool fillKey(const KeyBuffer& key, fscrypt_key* fs_key) {
+ if (key.size() != FS_AES_256_XTS_KEY_SIZE) {
LOG(ERROR) << "Wrong size key " << key.size();
return false;
}
- static_assert(EXT4_AES_256_XTS_KEY_SIZE <= sizeof(ext4_key->raw), "Key too long!");
- ext4_key->mode = EXT4_ENCRYPTION_MODE_AES_256_XTS;
- ext4_key->size = key.size();
- memset(ext4_key->raw, 0, sizeof(ext4_key->raw));
- memcpy(ext4_key->raw, key.data(), key.size());
+ static_assert(FS_AES_256_XTS_KEY_SIZE <= sizeof(fs_key->raw), "Key too long!");
+ fs_key->mode = FS_ENCRYPTION_MODE_AES_256_XTS;
+ fs_key->size = key.size();
+ memset(fs_key->raw, 0, sizeof(fs_key->raw));
+ memcpy(fs_key->raw, key.data(), key.size());
return true;
}
@@ -105,8 +93,8 @@
}
// Get the keyring we store all keys in
-static bool e4cryptKeyring(key_serial_t* device_keyring) {
- *device_keyring = keyctl_search(KEY_SPEC_SESSION_KEYRING, "keyring", "e4crypt", 0);
+static bool fscryptKeyring(key_serial_t* device_keyring) {
+ *device_keyring = keyctl_search(KEY_SPEC_SESSION_KEYRING, "keyring", "fscrypt", 0);
if (*device_keyring == -1) {
PLOG(ERROR) << "Unable to find device keyring";
return false;
@@ -117,25 +105,25 @@
// Install password into global keyring
// Return raw key reference for use in policy
bool installKey(const KeyBuffer& key, std::string* raw_ref) {
- // Place ext4_encryption_key into automatically zeroing buffer.
- KeyBuffer ext4KeyBuffer(sizeof(ext4_encryption_key));
- ext4_encryption_key& ext4_key = *reinterpret_cast<ext4_encryption_key*>(ext4KeyBuffer.data());
+ // Place fscrypt_key into automatically zeroing buffer.
+ KeyBuffer fsKeyBuffer(sizeof(fscrypt_key));
+ fscrypt_key& fs_key = *reinterpret_cast<fscrypt_key*>(fsKeyBuffer.data());
- if (!fillKey(key, &ext4_key)) return false;
+ if (!fillKey(key, &fs_key)) return false;
if (is_wrapped_key_supported()) {
/* When wrapped key is supported, only the first 32 bytes are
the same per boot. The second 32 bytes can change as the ephemeral
key is different. */
- *raw_ref = generateKeyRef(ext4_key.raw, (ext4_key.size)/2);
+ *raw_ref = generateKeyRef(fs_key.raw, (fs_key.size)/2);
} else {
- *raw_ref = generateKeyRef(ext4_key.raw, ext4_key.size);
+ *raw_ref = generateKeyRef(fs_key.raw, fs_key.size);
}
key_serial_t device_keyring;
- if (!e4cryptKeyring(&device_keyring)) return false;
+ if (!fscryptKeyring(&device_keyring)) return false;
for (char const* const* name_prefix = NAME_PREFIXES; *name_prefix != nullptr; name_prefix++) {
auto ref = keyname(*name_prefix, *raw_ref);
key_serial_t key_id =
- add_key("logon", ref.c_str(), (void*)&ext4_key, sizeof(ext4_key), device_keyring);
+ add_key("logon", ref.c_str(), (void*)&fs_key, sizeof(fs_key), device_keyring);
if (key_id == -1) {
PLOG(ERROR) << "Failed to insert key into keyring " << device_keyring;
return false;
@@ -148,7 +136,7 @@
bool evictKey(const std::string& raw_ref) {
key_serial_t device_keyring;
- if (!e4cryptKeyring(&device_keyring)) return false;
+ if (!fscryptKeyring(&device_keyring)) return false;
bool success = true;
for (char const* const* name_prefix = NAME_PREFIXES; *name_prefix != nullptr; name_prefix++) {
auto ref = keyname(*name_prefix, raw_ref);
diff --git a/MetadataCrypt.cpp b/MetadataCrypt.cpp
index 0934563..e156424 100644
--- a/MetadataCrypt.cpp
+++ b/MetadataCrypt.cpp
@@ -194,11 +194,11 @@
return true;
}
-bool e4crypt_mount_metadata_encrypted(const std::string& mount_point, bool needs_encrypt) {
- LOG(DEBUG) << "e4crypt_mount_metadata_encrypted: " << mount_point << " " << needs_encrypt;
+bool fscrypt_mount_metadata_encrypted(const std::string& mount_point, bool needs_encrypt) {
+ LOG(DEBUG) << "fscrypt_mount_metadata_encrypted: " << mount_point << " " << needs_encrypt;
auto encrypted_state = android::base::GetProperty("ro.crypto.state", "");
if (encrypted_state != "") {
- LOG(DEBUG) << "e4crypt_enable_crypto got unexpected starting state: " << encrypted_state;
+ LOG(DEBUG) << "fscrypt_enable_crypto got unexpected starting state: " << encrypted_state;
return false;
}
auto data_rec = fs_mgr_get_entry_for_mount_point(fstab_default, mount_point);
diff --git a/MetadataCrypt.h b/MetadataCrypt.h
index 841dc97..d82a43b 100644
--- a/MetadataCrypt.h
+++ b/MetadataCrypt.h
@@ -19,6 +19,6 @@
#include <string>
-bool e4crypt_mount_metadata_encrypted(const std::string& mount_point, bool needs_encrypt);
+bool fscrypt_mount_metadata_encrypted(const std::string& mount_point, bool needs_encrypt);
#endif
diff --git a/Utils.cpp b/Utils.cpp
index d348f71..f7afde5 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -19,6 +19,7 @@
#include "Process.h"
#include "sehandle.h"
+#include <android-base/chrono_utils.h>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
@@ -41,13 +42,16 @@
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <sys/wait.h>
+
#include <list>
#include <mutex>
+#include <thread>
#ifndef UMOUNT_NOFOLLOW
#define UMOUNT_NOFOLLOW 0x00000008 /* Don't follow symlink on umount */
#endif
+using namespace std::chrono_literals;
using android::base::ReadFileToString;
using android::base::StringPrintf;
@@ -814,7 +818,8 @@
result = -errno;
continue;
}
- std::unique_ptr<DIR, decltype(&closedir)> subdirp(fdopendir(subfd), closedir);
+ std::unique_ptr<DIR, decltype(&closedir)> subdirp(
+ android::base::Fdopendir(std::move(subfd)), closedir);
if (!subdirp) {
PLOG(ERROR) << "Couldn't fdopendir " << name;
result = -errno;
@@ -858,5 +863,20 @@
return OK;
}
+// TODO(118708649): fix duplication with init/util.h
+status_t WaitForFile(const char* filename, std::chrono::nanoseconds timeout) {
+ android::base::Timer t;
+ while (t.duration() < timeout) {
+ struct stat sb;
+ if (stat(filename, &sb) != -1) {
+ LOG(INFO) << "wait for '" << filename << "' took " << t;
+ return 0;
+ }
+ std::this_thread::sleep_for(10ms);
+ }
+ LOG(WARNING) << "wait for '" << filename << "' timed out and took " << t;
+ return -1;
+}
+
} // namespace vold
} // namespace android
diff --git a/Utils.h b/Utils.h
index b097625..e6f4792 100644
--- a/Utils.h
+++ b/Utils.h
@@ -24,6 +24,7 @@
#include <selinux/selinux.h>
#include <utils/Errors.h>
+#include <chrono>
#include <string>
#include <vector>
@@ -134,6 +135,8 @@
status_t DeleteDirContentsAndDir(const std::string& pathname);
+status_t WaitForFile(const char* filename, std::chrono::nanoseconds timeout);
+
} // namespace vold
} // namespace android
diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp
index 056f29a..496a0b8 100644
--- a/VoldNativeService.cpp
+++ b/VoldNativeService.cpp
@@ -25,7 +25,7 @@
#include "VolumeManager.h"
#include "Checkpoint.h"
-#include "Ext4Crypt.h"
+#include "FsCrypt.h"
#include "MetadataCrypt.h"
#include "cryptfs.h"
@@ -35,8 +35,8 @@
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
-#include <ext4_utils/ext4_crypt.h>
#include <fs_mgr.h>
+#include <fscrypt/fscrypt.h>
#include <private/android_filesystem_config.h>
#include <utils/Trace.h>
@@ -191,11 +191,11 @@
}
binder::Status checkArgumentSandboxId(const std::string& sandboxId) {
- // sandboxId will be in either the format shared:<shared-user-id> or <package-name>
+ // sandboxId will be in either the format shared-<shared-user-id> or <package-name>
// and <shared-user-id> name has same requirements as <package-name>.
std::size_t nameStartIndex = 0;
- if (android::base::StartsWith(sandboxId, "shared:")) {
- nameStartIndex = 7; // len("shared:")
+ if (android::base::StartsWith(sandboxId, "shared-")) {
+ nameStartIndex = 7; // len("shared-")
}
return checkArgumentPackageName(sandboxId.substr(nameStartIndex));
}
@@ -358,12 +358,16 @@
}
binder::Status VoldNativeService::onUserStarted(int32_t userId,
- const std::vector<std::string>& packageNames) {
+ const std::vector<std::string>& packageNames,
+ const std::vector<int>& appIds,
+ const std::vector<std::string>& sandboxIds) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PACKAGE_NAMES(packageNames);
+ CHECK_ARGUMENT_SANDBOX_IDS(sandboxIds);
ACQUIRE_LOCK;
- return translate(VolumeManager::Instance()->onUserStarted(userId, packageNames));
+ return translate(
+ VolumeManager::Instance()->onUserStarted(userId, packageNames, appIds, sandboxIds));
}
binder::Status VoldNativeService::onUserStopped(int32_t userId) {
@@ -600,6 +604,29 @@
return translate(VolumeManager::Instance()->destroyObb(volId));
}
+binder::Status VoldNativeService::createStubVolume(
+ const std::string& sourcePath, const std::string& mountPath, const std::string& fsType,
+ const std::string& fsUuid, const std::string& fsLabel, std::string* _aidl_return) {
+ ENFORCE_UID(AID_SYSTEM);
+ CHECK_ARGUMENT_PATH(sourcePath);
+ CHECK_ARGUMENT_PATH(mountPath);
+ CHECK_ARGUMENT_HEX(fsUuid);
+ // Label limitation seems to be different between fs (including allowed characters), so checking
+ // is quite meaningless.
+ ACQUIRE_LOCK;
+
+ return translate(VolumeManager::Instance()->createStubVolume(sourcePath, mountPath, fsType,
+ fsUuid, fsLabel, _aidl_return));
+}
+
+binder::Status VoldNativeService::destroyStubVolume(const std::string& volId) {
+ ENFORCE_UID(AID_SYSTEM);
+ CHECK_ARGUMENT_ID(volId);
+ ACQUIRE_LOCK;
+
+ return translate(VolumeManager::Instance()->destroyStubVolume(volId));
+}
+
binder::Status VoldNativeService::fstrim(
int32_t fstrimFlags, const android::sp<android::os::IVoldTaskListener>& listener) {
ENFORCE_UID(AID_SYSTEM);
@@ -695,11 +722,11 @@
ACQUIRE_CRYPT_LOCK;
LOG(DEBUG) << "fdeEnable(" << passwordType << ", *, " << encryptionFlags << ")";
- if (e4crypt_is_native()) {
- LOG(ERROR) << "e4crypt_is_native, fdeEnable invalid";
- return error("e4crypt_is_native, fdeEnable invalid");
+ if (fscrypt_is_native()) {
+ LOG(ERROR) << "fscrypt_is_native, fdeEnable invalid";
+ return error("fscrypt_is_native, fdeEnable invalid");
}
- LOG(DEBUG) << "!e4crypt_is_native, spawning fdeEnableInternal";
+ LOG(DEBUG) << "!fscrypt_is_native, spawning fdeEnableInternal";
// Spawn as thread so init can issue commands back to vold without
// causing deadlock, usually as a result of prep_data_fs.
@@ -774,14 +801,14 @@
ENFORCE_UID(AID_SYSTEM);
ACQUIRE_CRYPT_LOCK;
- return translateBool(e4crypt_initialize_global_de());
+ return translateBool(fscrypt_initialize_global_de());
}
binder::Status VoldNativeService::mountDefaultEncrypted() {
ENFORCE_UID(AID_SYSTEM);
ACQUIRE_CRYPT_LOCK;
- if (!e4crypt_is_native()) {
+ if (!fscrypt_is_native()) {
// Spawn as thread so init can issue commands back to vold without
// causing deadlock, usually as a result of prep_data_fs.
std::thread(&cryptfs_mount_default_encrypted).detach();
@@ -793,7 +820,7 @@
ENFORCE_UID(AID_SYSTEM);
ACQUIRE_CRYPT_LOCK;
- return translateBool(e4crypt_init_user0());
+ return translateBool(fscrypt_init_user0());
}
binder::Status VoldNativeService::isConvertibleToFbe(bool* _aidl_return) {
@@ -808,28 +835,28 @@
ENFORCE_UID(AID_SYSTEM);
ACQUIRE_LOCK;
- return translateBool(e4crypt_mount_metadata_encrypted(mountPoint, false));
+ return translateBool(fscrypt_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));
+ return translateBool(fscrypt_mount_metadata_encrypted(mountPoint, true));
}
binder::Status VoldNativeService::createUserKey(int32_t userId, int32_t userSerial, bool ephemeral) {
ENFORCE_UID(AID_SYSTEM);
ACQUIRE_CRYPT_LOCK;
- return translateBool(e4crypt_vold_create_user_key(userId, userSerial, ephemeral));
+ return translateBool(fscrypt_vold_create_user_key(userId, userSerial, ephemeral));
}
binder::Status VoldNativeService::destroyUserKey(int32_t userId) {
ENFORCE_UID(AID_SYSTEM);
ACQUIRE_CRYPT_LOCK;
- return translateBool(e4crypt_destroy_user_key(userId));
+ return translateBool(fscrypt_destroy_user_key(userId));
}
binder::Status VoldNativeService::addUserKeyAuth(int32_t userId, int32_t userSerial,
@@ -838,7 +865,7 @@
ENFORCE_UID(AID_SYSTEM);
ACQUIRE_CRYPT_LOCK;
- return translateBool(e4crypt_add_user_key_auth(userId, userSerial, token, secret));
+ return translateBool(fscrypt_add_user_key_auth(userId, userSerial, token, secret));
}
binder::Status VoldNativeService::clearUserKeyAuth(int32_t userId, int32_t userSerial,
@@ -846,14 +873,14 @@
ENFORCE_UID(AID_SYSTEM);
ACQUIRE_CRYPT_LOCK;
- return translateBool(e4crypt_clear_user_key_auth(userId, userSerial, token, secret));
+ return translateBool(fscrypt_clear_user_key_auth(userId, userSerial, token, secret));
}
binder::Status VoldNativeService::fixateNewestUserKeyAuth(int32_t userId) {
ENFORCE_UID(AID_SYSTEM);
ACQUIRE_CRYPT_LOCK;
- return translateBool(e4crypt_fixate_newest_user_key_auth(userId));
+ return translateBool(fscrypt_fixate_newest_user_key_auth(userId));
}
binder::Status VoldNativeService::unlockUserKey(int32_t userId, int32_t userSerial,
@@ -862,14 +889,14 @@
ENFORCE_UID(AID_SYSTEM);
ACQUIRE_CRYPT_LOCK;
- return translateBool(e4crypt_unlock_user_key(userId, userSerial, token, secret));
+ return translateBool(fscrypt_unlock_user_key(userId, userSerial, token, secret));
}
binder::Status VoldNativeService::lockUserKey(int32_t userId) {
ENFORCE_UID(AID_SYSTEM);
ACQUIRE_CRYPT_LOCK;
- return translateBool(e4crypt_lock_user_key(userId));
+ return translateBool(fscrypt_lock_user_key(userId));
}
binder::Status VoldNativeService::prepareUserStorage(const std::unique_ptr<std::string>& uuid,
@@ -881,7 +908,7 @@
CHECK_ARGUMENT_HEX(uuid_);
ACQUIRE_CRYPT_LOCK;
- return translateBool(e4crypt_prepare_user_storage(uuid_, userId, userSerial, flags));
+ return translateBool(fscrypt_prepare_user_storage(uuid_, userId, userSerial, flags));
}
binder::Status VoldNativeService::destroyUserStorage(const std::unique_ptr<std::string>& uuid,
@@ -892,7 +919,7 @@
CHECK_ARGUMENT_HEX(uuid_);
ACQUIRE_CRYPT_LOCK;
- return translateBool(e4crypt_destroy_user_storage(uuid_, userId, flags));
+ return translateBool(fscrypt_destroy_user_storage(uuid_, userId, flags));
}
binder::Status VoldNativeService::prepareSandboxForApp(const std::string& packageName,
@@ -908,7 +935,7 @@
}
binder::Status VoldNativeService::destroySandboxForApp(const std::string& packageName,
- int32_t appId, const std::string& sandboxId,
+ const std::string& sandboxId,
int32_t userId) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
@@ -916,7 +943,7 @@
ACQUIRE_LOCK;
return translate(
- VolumeManager::Instance()->destroySandboxForApp(packageName, appId, sandboxId, userId));
+ VolumeManager::Instance()->destroySandboxForApp(packageName, sandboxId, userId));
}
binder::Status VoldNativeService::startCheckpoint(int32_t retry) {
diff --git a/VoldNativeService.h b/VoldNativeService.h
index b1f28c9..36b591a 100644
--- a/VoldNativeService.h
+++ b/VoldNativeService.h
@@ -39,7 +39,9 @@
binder::Status onUserAdded(int32_t userId, int32_t userSerial);
binder::Status onUserRemoved(int32_t userId);
- binder::Status onUserStarted(int32_t userId, const std::vector<std::string>& packageNames);
+ binder::Status onUserStarted(int32_t userId, const std::vector<std::string>& packageNames,
+ const std::vector<int>& appIds,
+ const std::vector<std::string>& sandboxIds);
binder::Status onUserStopped(int32_t userId);
binder::Status addAppIds(const std::vector<std::string>& packageNames,
@@ -70,6 +72,11 @@
int32_t ownerGid, std::string* _aidl_return);
binder::Status destroyObb(const std::string& volId);
+ binder::Status createStubVolume(const std::string& sourcePath, const std::string& mountPath,
+ const std::string& fsType, const std::string& fsUuid,
+ const std::string& fsLabel, std::string* _aidl_return);
+ binder::Status destroyStubVolume(const std::string& volId);
+
binder::Status fstrim(int32_t fstrimFlags,
const android::sp<android::os::IVoldTaskListener>& listener);
binder::Status runIdleMaint(const android::sp<android::os::IVoldTaskListener>& listener);
@@ -122,7 +129,7 @@
binder::Status prepareSandboxForApp(const std::string& packageName, int32_t appId,
const std::string& sandboxId, int32_t userId);
- binder::Status destroySandboxForApp(const std::string& packageName, int32_t appId,
+ binder::Status destroySandboxForApp(const std::string& packageName,
const std::string& sandboxId, int32_t userId);
binder::Status startCheckpoint(int32_t retry);
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 45158fe..f3604ee 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -49,10 +49,10 @@
#include <private/android_filesystem_config.h>
-#include <ext4_utils/ext4_crypt.h>
+#include <fscrypt/fscrypt.h>
#include "Devmapper.h"
-#include "Ext4Crypt.h"
+#include "FsCrypt.h"
#include "Loop.h"
#include "NetlinkManager.h"
#include "Process.h"
@@ -65,6 +65,7 @@
#include "fs/Vfat.h"
#include "model/EmulatedVolume.h"
#include "model/ObbVolume.h"
+#include "model/StubVolume.h"
using android::base::GetBoolProperty;
using android::base::StartsWith;
@@ -97,6 +98,7 @@
VolumeManager::VolumeManager() {
mDebug = false;
mNextObbId = 0;
+ mNextStubVolumeId = 0;
// For security reasons, assume that a secure keyguard is
// showing until we hear otherwise
mSecureKeyguardShowing = true;
@@ -310,6 +312,11 @@
return vol;
}
}
+ for (const auto& vol : mStubVolumes) {
+ if (vol->getId() == id) {
+ return vol;
+ }
+ }
for (const auto& vol : mObbVolumes) {
if (vol->getId() == id) {
return vol;
@@ -338,8 +345,8 @@
LOG(ERROR) << "Failed to unlink " << keyPath;
success = false;
}
- if (e4crypt_is_native()) {
- if (!e4crypt_destroy_volume_keys(fsUuid)) {
+ if (fscrypt_is_native()) {
+ if (!fscrypt_destroy_volume_keys(fsUuid)) {
success = false;
}
}
@@ -568,13 +575,6 @@
if (sandboxRoot.empty()) {
return -errno;
}
- std::string sharedSandboxRoot;
- StringAppendF(&sharedSandboxRoot, "%s/shared", sandboxRoot.c_str());
- // Create shared sandbox base dir for apps with sharedUserIds
- if (fs_prepare_dir(sharedSandboxRoot.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) {
- PLOG(ERROR) << "fs_prepare_dir failed on " << sharedSandboxRoot;
- return -errno;
- }
if (!createPkgSpecificDirRoots(volumeRoot)) {
return -errno;
@@ -691,11 +691,7 @@
std::string VolumeManager::prepareSandboxSource(uid_t uid, const std::string& sandboxId,
const std::string& sandboxRootDir) {
std::string sandboxSourceDir(sandboxRootDir);
- if (StartsWith(sandboxId, "shared:")) {
- StringAppendF(&sandboxSourceDir, "/shared/%s", sandboxId.substr(7).c_str());
- } else {
- StringAppendF(&sandboxSourceDir, "/%s", sandboxId.c_str());
- }
+ StringAppendF(&sandboxSourceDir, "/%s", sandboxId.c_str());
if (fs_prepare_dir(sandboxSourceDir.c_str(), 0755, uid, uid) != 0) {
PLOG(ERROR) << "fs_prepare_dir failed on " << sandboxSourceDir;
return kEmptyString;
@@ -772,7 +768,9 @@
return 0;
}
-int VolumeManager::onUserStarted(userid_t userId, const std::vector<std::string>& packageNames) {
+int VolumeManager::onUserStarted(userid_t userId, const std::vector<std::string>& packageNames,
+ const std::vector<int>& appIds,
+ const std::vector<std::string>& sandboxIds) {
LOG(VERBOSE) << "onUserStarted: " << userId;
// Note that sometimes the system will spin up processes from Zygote
// before actually starting the user, so we're okay if Zygote
@@ -782,6 +780,10 @@
mStartedUsers.insert(userId);
mUserPackages[userId] = packageNames;
+ for (size_t i = 0; i < packageNames.size(); ++i) {
+ mAppIds[packageNames[i]] = appIds[i];
+ mSandboxIds[appIds[i]] = sandboxIds[i];
+ }
if (mPrimary) {
linkPrimary(userId);
}
@@ -863,13 +865,13 @@
return prepareSandboxes(userId, {packageName}, visibleVolLabels);
}
-int VolumeManager::destroySandboxForApp(const std::string& packageName, appid_t appId,
+int VolumeManager::destroySandboxForApp(const std::string& packageName,
const std::string& sandboxId, userid_t userId) {
if (!GetBoolProperty(kIsolatedStorage, false)) {
return 0;
}
- LOG(VERBOSE) << "destroySandboxForApp: " << packageName << ", appId=" << appId
- << ", sandboxId=" << sandboxId << ", userId=" << userId;
+ LOG(VERBOSE) << "destroySandboxForApp: " << packageName << ", sandboxId=" << sandboxId
+ << ", userId=" << userId;
auto& userPackages = mUserPackages[userId];
std::remove(userPackages.begin(), userPackages.end(), packageName);
// If the package is not uninstalled in any other users, remove appId and sandboxId
@@ -883,8 +885,11 @@
}
}
if (!installedInAnyUser) {
- mAppIds.erase(packageName);
- mSandboxIds.erase(appId);
+ const auto& entry = mAppIds.find(packageName);
+ if (entry != mAppIds.end()) {
+ mSandboxIds.erase(entry->second);
+ mAppIds.erase(entry);
+ }
}
std::vector<std::string> visibleVolLabels;
@@ -915,11 +920,7 @@
if (volLabel == mPrimary->getLabel() && mPrimary->isEmulated()) {
StringAppendF(&sandboxDir, "/%d", userId);
}
- if (StartsWith(sandboxId, "shared:")) {
- StringAppendF(&sandboxDir, "/Android/sandbox/shared/%s", sandboxId.substr(7).c_str());
- } else {
- StringAppendF(&sandboxDir, "/Android/sandbox/%s", sandboxId.c_str());
- }
+ StringAppendF(&sandboxDir, "/Android/sandbox/%s", sandboxId.c_str());
if (android::vold::DeleteDirContentsAndDir(sandboxDir) < 0) {
PLOG(ERROR) << "DeleteDirContentsAndDir failed on " << sandboxDir;
@@ -1196,6 +1197,7 @@
for (const auto& disk : mDisks) {
disk->destroy();
}
+ mStubVolumes.clear();
mDisks.clear();
mPendingDisks.clear();
android::vold::sSleepOnUnmount = true;
@@ -1210,6 +1212,9 @@
if (mInternalEmulated != nullptr) {
mInternalEmulated->unmount();
}
+ for (const auto& stub : mStubVolumes) {
+ stub->unmount();
+ }
for (const auto& disk : mDisks) {
disk->unmountAll();
}
@@ -1423,6 +1428,32 @@
return android::OK;
}
+int VolumeManager::createStubVolume(const std::string& sourcePath, const std::string& mountPath,
+ const std::string& fsType, const std::string& fsUuid,
+ const std::string& fsLabel, std::string* outVolId) {
+ int id = mNextStubVolumeId++;
+ auto vol = std::shared_ptr<android::vold::VolumeBase>(
+ new android::vold::StubVolume(id, sourcePath, mountPath, fsType, fsUuid, fsLabel));
+ vol->create();
+
+ mStubVolumes.push_back(vol);
+ *outVolId = vol->getId();
+ return android::OK;
+}
+
+int VolumeManager::destroyStubVolume(const std::string& volId) {
+ auto i = mStubVolumes.begin();
+ while (i != mStubVolumes.end()) {
+ if ((*i)->getId() == volId) {
+ (*i)->destroy();
+ i = mStubVolumes.erase(i);
+ } else {
+ ++i;
+ }
+ }
+ return android::OK;
+}
+
int VolumeManager::mountAppFuse(uid_t uid, pid_t pid, int mountId, unique_fd* device_fd) {
std::string name = std::to_string(mountId);
diff --git a/VolumeManager.h b/VolumeManager.h
index 8982d8f..e25e244 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -90,7 +90,8 @@
int onUserAdded(userid_t userId, int userSerialNumber);
int onUserRemoved(userid_t userId);
- int onUserStarted(userid_t userId, const std::vector<std::string>& packageNames);
+ int onUserStarted(userid_t userId, const std::vector<std::string>& packageNames,
+ const std::vector<int>& appIds, const std::vector<std::string>& sandboxIds);
int onUserStopped(userid_t userId);
int addAppIds(const std::vector<std::string>& packageNames, const std::vector<int32_t>& appIds);
@@ -98,8 +99,8 @@
const std::vector<std::string>& sandboxIds);
int prepareSandboxForApp(const std::string& packageName, appid_t appId,
const std::string& sandboxId, userid_t userId);
- int destroySandboxForApp(const std::string& packageName, appid_t appId,
- const std::string& sandboxId, userid_t userId);
+ int destroySandboxForApp(const std::string& packageName, const std::string& sandboxId,
+ userid_t userId);
int onVolumeMounted(android::vold::VolumeBase* vol);
int onVolumeUnmounted(android::vold::VolumeBase* vol);
@@ -135,6 +136,11 @@
std::string* outVolId);
int destroyObb(const std::string& volId);
+ int createStubVolume(const std::string& sourcePath, const std::string& mountPath,
+ const std::string& fsType, const std::string& fsUuid,
+ const std::string& fsLabel, std::string* outVolId);
+ int destroyStubVolume(const std::string& volId);
+
int mountAppFuse(uid_t uid, pid_t pid, int mountId, android::base::unique_fd* device_fd);
int unmountAppFuse(uid_t uid, pid_t pid, int mountId);
@@ -180,6 +186,7 @@
std::list<std::shared_ptr<android::vold::Disk>> mDisks;
std::list<std::shared_ptr<android::vold::Disk>> mPendingDisks;
std::list<std::shared_ptr<android::vold::VolumeBase>> mObbVolumes;
+ std::list<std::shared_ptr<android::vold::VolumeBase>> mStubVolumes;
std::unordered_map<userid_t, int> mAddedUsers;
std::unordered_set<userid_t> mStartedUsers;
@@ -195,6 +202,7 @@
std::unordered_set<std::string> mVisibleVolumeIds;
int mNextObbId;
+ int mNextStubVolumeId;
bool mSecureKeyguardShowing;
};
diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl
index d8b36aa..ca0afdc 100644
--- a/binder/android/os/IVold.aidl
+++ b/binder/android/os/IVold.aidl
@@ -29,7 +29,8 @@
void onUserAdded(int userId, int userSerial);
void onUserRemoved(int userId);
- void onUserStarted(int userId, in @utf8InCpp String[] packageNames);
+ void onUserStarted(int userId, in @utf8InCpp String[] packageNames, in int[] appIds,
+ in @utf8InCpp String[] sandboxIds);
void onUserStopped(int userId);
void addAppIds(in @utf8InCpp String[] packageNames, in int[] appIds);
@@ -102,7 +103,7 @@
void prepareSandboxForApp(in @utf8InCpp String packageName, int appId,
in @utf8InCpp String sandboxId, int userId);
- void destroySandboxForApp(in @utf8InCpp String packageName, int appId,
+ void destroySandboxForApp(in @utf8InCpp String packageName,
in @utf8InCpp String sandboxId, int userId);
void startCheckpoint(int retry);
@@ -114,6 +115,11 @@
void restoreCheckpoint(@utf8InCpp String device);
void markBootAttempt();
+ @utf8InCpp String createStubVolume(@utf8InCpp String sourcePath,
+ @utf8InCpp String mountPath, @utf8InCpp String fsType,
+ @utf8InCpp String fsUuid, @utf8InCpp String fsLabel);
+ void destroyStubVolume(@utf8InCpp String volId);
+
const int ENCRYPTION_FLAG_NO_UI = 4;
const int ENCRYPTION_STATE_NONE = 1;
@@ -161,4 +167,5 @@
const int VOLUME_TYPE_EMULATED = 2;
const int VOLUME_TYPE_ASEC = 3;
const int VOLUME_TYPE_OBB = 4;
+ const int VOLUME_TYPE_STUB = 5;
}
diff --git a/cryptfs.cpp b/cryptfs.cpp
index 68f83da..21f434d 100644
--- a/cryptfs.cpp
+++ b/cryptfs.cpp
@@ -26,10 +26,11 @@
#include "Checkpoint.h"
#include "EncryptInplace.h"
-#include "Ext4Crypt.h"
+#include "FsCrypt.h"
#include "Keymaster.h"
#include "Process.h"
#include "ScryptParameters.h"
+#include "Utils.h"
#include "VoldUtil.h"
#include "VolumeManager.h"
#include "secontext.h"
@@ -38,10 +39,10 @@
#include <bootloader_message/bootloader_message.h>
#include <cutils/android_reboot.h>
#include <cutils/properties.h>
-#include <ext4_utils/ext4_crypt.h>
#include <ext4_utils/ext4_utils.h>
#include <f2fs_sparseblock.h>
#include <fs_mgr.h>
+#include <fscrypt/fscrypt.h>
#include <hardware_legacy/power.h>
#include <log/log.h>
#include <logwrap/logwrap.h>
@@ -76,6 +77,8 @@
#include <crypto_scrypt.h>
}
+using namespace std::chrono_literals;
+
#define UNUSED __attribute__((unused))
#define DM_CRYPT_BUF_SIZE 4096
@@ -1321,6 +1324,12 @@
goto errout;
}
+ /* Ensure the dm device has been created before returning. */
+ if (android::vold::WaitForFile(crypto_blk_name, 1s) < 0) {
+ // WaitForFile generates a suitable log message
+ goto errout;
+ }
+
/* We made it here with no errors. Woot! */
retval = 0;
@@ -1874,7 +1883,7 @@
int cryptfs_restart(void) {
SLOGI("cryptfs_restart");
- if (e4crypt_is_native()) {
+ if (fscrypt_is_native()) {
SLOGE("cryptfs_restart not valid for file encryption:");
return -1;
}
@@ -1895,7 +1904,7 @@
}
// crypto_complete is full disk encrypted status
- if (e4crypt_is_native()) {
+ if (fscrypt_is_native()) {
return CRYPTO_COMPLETE_NOT_ENCRYPTED;
}
@@ -2155,7 +2164,7 @@
strlcpy((char*)ext_crypt_ftr.crypto_type_name, cryptfs_get_crypto_name(),
MAX_CRYPTO_TYPE_NAME_LEN);
uint32_t flags = 0;
- if (e4crypt_is_native() &&
+ if (fscrypt_is_native() &&
android::base::GetBoolProperty("ro.crypto.allow_encrypt_override", false))
flags |= CREATE_CRYPTO_BLK_DEV_FLAGS_ALLOW_ENCRYPT_OVERRIDE;
@@ -2254,7 +2263,7 @@
int cryptfs_check_passwd(const char* passwd) {
SLOGI("cryptfs_check_passwd");
- if (e4crypt_is_native()) {
+ if (fscrypt_is_native()) {
SLOGE("cryptfs_check_passwd not valid for file encryption");
return -1;
}
@@ -2890,7 +2899,7 @@
}
int cryptfs_changepw(int crypt_type, const char* currentpw, const char* newpw) {
- if (e4crypt_is_native()) {
+ if (fscrypt_is_native()) {
SLOGE("cryptfs_changepw not valid for file encryption");
return -1;
}
@@ -3158,7 +3167,7 @@
/* Return the value of the specified field. */
int cryptfs_getfield(const char* fieldname, char* value, int len) {
- if (e4crypt_is_native()) {
+ if (fscrypt_is_native()) {
SLOGE("Cannot get field when file encrypted");
return -1;
}
@@ -3223,7 +3232,7 @@
/* Set the value of the specified field. */
int cryptfs_setfield(const char* fieldname, const char* value) {
- if (e4crypt_is_native()) {
+ if (fscrypt_is_native()) {
SLOGE("Cannot set field when file encrypted");
return -1;
}
@@ -3343,7 +3352,7 @@
/* Returns type of the password, default, pattern, pin or password.
*/
int cryptfs_get_password_type(void) {
- if (e4crypt_is_native()) {
+ if (fscrypt_is_native()) {
SLOGE("cryptfs_get_password_type not valid for file encryption");
return -1;
}
@@ -3363,7 +3372,7 @@
}
const char* cryptfs_get_password() {
- if (e4crypt_is_native()) {
+ if (fscrypt_is_native()) {
SLOGE("cryptfs_get_password not valid for file encryption");
return 0;
}
diff --git a/fs/Ext4.cpp b/fs/Ext4.cpp
index 7ac4853..806cfd1 100644
--- a/fs/Ext4.cpp
+++ b/fs/Ext4.cpp
@@ -36,12 +36,12 @@
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <cutils/properties.h>
-#include <ext4_utils/ext4_crypt.h>
+#include <fscrypt/fscrypt.h>
#include <logwrap/logwrap.h>
#include <selinux/selinux.h>
#include "Ext4.h"
-#include "Ext4Crypt.h"
+#include "FsCrypt.h"
#include "Utils.h"
#include "VoldUtil.h"
@@ -175,7 +175,7 @@
if (android::base::GetBoolProperty("vold.has_quota", false)) {
options += ",quota";
}
- if (e4crypt_is_native()) {
+ if (fscrypt_is_native()) {
options += ",encrypt";
}
diff --git a/fs/F2fs.cpp b/fs/F2fs.cpp
index 9d72963..c6e0f52 100644
--- a/fs/F2fs.cpp
+++ b/fs/F2fs.cpp
@@ -20,7 +20,7 @@
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
-#include <ext4_utils/ext4_crypt.h>
+#include <fscrypt/fscrypt.h>
#include <string>
#include <vector>
@@ -81,7 +81,7 @@
cmd.push_back("-O");
cmd.push_back("quota");
}
- if (e4crypt_is_native()) {
+ if (fscrypt_is_native()) {
cmd.push_back("-O");
cmd.push_back("encrypt");
}
diff --git a/model/Disk.cpp b/model/Disk.cpp
index 2b6773d..3d25e4c 100644
--- a/model/Disk.cpp
+++ b/model/Disk.cpp
@@ -15,7 +15,7 @@
*/
#include "Disk.h"
-#include "Ext4Crypt.h"
+#include "FsCrypt.h"
#include "PrivateVolume.h"
#include "PublicVolume.h"
#include "Utils.h"
@@ -28,7 +28,7 @@
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
-#include <ext4_utils/ext4_crypt.h>
+#include <fscrypt/fscrypt.h>
#include "cryptfs.h"
diff --git a/model/StubVolume.cpp b/model/StubVolume.cpp
new file mode 100644
index 0000000..edd0861
--- /dev/null
+++ b/model/StubVolume.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "StubVolume.h"
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+
+using android::base::StringPrintf;
+
+namespace android {
+namespace vold {
+
+StubVolume::StubVolume(int id, const std::string& sourcePath, const std::string& mountPath,
+ const std::string& fsType, const std::string& fsUuid,
+ const std::string& fsLabel)
+ : VolumeBase(Type::kStub),
+ mSourcePath(sourcePath),
+ mMountPath(mountPath),
+ mFsType(fsType),
+ mFsUuid(fsUuid),
+ mFsLabel(fsLabel) {
+ setId(StringPrintf("stub:%d", id));
+}
+
+StubVolume::~StubVolume() {}
+
+status_t StubVolume::doCreate() {
+ return OK;
+}
+
+status_t StubVolume::doDestroy() {
+ return OK;
+}
+
+status_t StubVolume::doMount() {
+ auto listener = getListener();
+ if (listener) listener->onVolumeMetadataChanged(getId(), mFsType, mFsUuid, mFsLabel);
+ setInternalPath(mSourcePath);
+ setPath(mMountPath);
+ return OK;
+}
+
+status_t StubVolume::doUnmount() {
+ return OK;
+}
+
+// TODO: return error instead.
+status_t StubVolume::doFormat(const std::string& fsType) {
+ return OK;
+}
+
+} // namespace vold
+} // namespace android
diff --git a/model/StubVolume.h b/model/StubVolume.h
new file mode 100644
index 0000000..538cae9
--- /dev/null
+++ b/model/StubVolume.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_VOLD_STUB_VOLUME_H
+#define ANDROID_VOLD_STUB_VOLUME_H
+
+#include "VolumeBase.h"
+
+namespace android {
+namespace vold {
+
+/*
+ * A vold representation of volumes managed from outside Android (e.g., ARC++).
+ *
+ * Used for the case when events such that mounting and unmounting are
+ * actually handled from outside vold, and vold only need to keep track on those
+ * vents instead of talking to kernel directly.
+ */
+class StubVolume : public VolumeBase {
+ public:
+ StubVolume(int id, const std::string& sourcePath, const std::string& mountPath,
+ const std::string& fsType, const std::string& fsUuid, const std::string& fsLabel);
+ virtual ~StubVolume();
+
+ protected:
+ status_t doCreate() override;
+ status_t doDestroy() override;
+ status_t doMount() override;
+ status_t doUnmount() override;
+ status_t doFormat(const std::string& fsType) override;
+
+ private:
+ const std::string mSourcePath;
+ const std::string mMountPath;
+ const std::string mFsType;
+ const std::string mFsUuid;
+ const std::string mFsLabel;
+
+ DISALLOW_COPY_AND_ASSIGN(StubVolume);
+};
+
+} // namespace vold
+} // namespace android
+
+#endif
diff --git a/model/VolumeBase.h b/model/VolumeBase.h
index a9fd42d..ea187bd 100644
--- a/model/VolumeBase.h
+++ b/model/VolumeBase.h
@@ -56,6 +56,7 @@
kEmulated,
kAsec,
kObb,
+ kStub,
};
enum MountFlags {