Move over to the C++ Fstab class
Test: build and boot Change-Id: Id3850c9c133f6644073a2439368501253a2a94a9
This commit is contained in:
parent
eb00112e09
commit
4c5bde2b92
8 changed files with 153 additions and 138 deletions
|
@ -39,6 +39,9 @@
|
||||||
|
|
||||||
using android::base::SetProperty;
|
using android::base::SetProperty;
|
||||||
using android::binder::Status;
|
using android::binder::Status;
|
||||||
|
using android::fs_mgr::Fstab;
|
||||||
|
using android::fs_mgr::ReadDefaultFstab;
|
||||||
|
using android::fs_mgr::ReadFstabFromFile;
|
||||||
using android::hardware::hidl_string;
|
using android::hardware::hidl_string;
|
||||||
using android::hardware::boot::V1_0::BoolResult;
|
using android::hardware::boot::V1_0::BoolResult;
|
||||||
using android::hardware::boot::V1_0::IBootControl;
|
using android::hardware::boot::V1_0::IBootControl;
|
||||||
|
@ -69,12 +72,13 @@ bool setBowState(std::string const& block_device, std::string const& state) {
|
||||||
|
|
||||||
Status cp_supportsCheckpoint(bool& result) {
|
Status cp_supportsCheckpoint(bool& result) {
|
||||||
result = false;
|
result = false;
|
||||||
auto fstab_default = std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)>{
|
Fstab fstab_default;
|
||||||
fs_mgr_read_fstab_default(), fs_mgr_free_fstab};
|
if (!ReadDefaultFstab(&fstab_default)) {
|
||||||
if (!fstab_default) return Status::fromExceptionCode(EINVAL, "Failed to get fstab");
|
return Status::fromExceptionCode(EINVAL, "Failed to get fstab");
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < fstab_default->num_entries; ++i) {
|
for (const auto& entry : fstab_default) {
|
||||||
if (fs_mgr_is_checkpoint(&fstab_default->recs[i])) {
|
if (entry.fs_mgr_flags.checkpoint_blk || entry.fs_mgr_flags.checkpoint_fs) {
|
||||||
result = true;
|
result = true;
|
||||||
return Status::ok();
|
return Status::ok();
|
||||||
}
|
}
|
||||||
|
@ -112,32 +116,31 @@ Status cp_commitChanges() {
|
||||||
// But we also need to get the matching fstab entries to see
|
// But we also need to get the matching fstab entries to see
|
||||||
// the original flags
|
// the original flags
|
||||||
std::string err_str;
|
std::string err_str;
|
||||||
auto fstab_default = std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)>{
|
Fstab fstab_default;
|
||||||
fs_mgr_read_fstab_default(), fs_mgr_free_fstab};
|
if (!ReadDefaultFstab(&fstab_default)) {
|
||||||
if (!fstab_default) return Status::fromExceptionCode(EINVAL, "Failed to get fstab");
|
return Status::fromExceptionCode(EINVAL, "Failed to get fstab");
|
||||||
|
}
|
||||||
|
|
||||||
auto mounts = std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)>{
|
Fstab mounts;
|
||||||
fs_mgr_read_fstab("/proc/mounts"), fs_mgr_free_fstab};
|
if (!ReadFstabFromFile("/proc/mounts", &mounts)) {
|
||||||
if (!mounts) return Status::fromExceptionCode(EINVAL, "Failed to get /proc/mounts");
|
return Status::fromExceptionCode(EINVAL, "Failed to get /proc/mounts");
|
||||||
|
}
|
||||||
|
|
||||||
// Walk mounted file systems
|
// Walk mounted file systems
|
||||||
for (int i = 0; i < mounts->num_entries; ++i) {
|
for (const auto& mount_rec : mounts) {
|
||||||
const fstab_rec* mount_rec = &mounts->recs[i];
|
const auto fstab_rec = GetEntryForMountPoint(&fstab_default, mount_rec.mount_point);
|
||||||
const fstab_rec* fstab_rec =
|
|
||||||
fs_mgr_get_entry_for_mount_point(fstab_default.get(), mount_rec->mount_point);
|
|
||||||
if (!fstab_rec) continue;
|
if (!fstab_rec) continue;
|
||||||
|
|
||||||
if (fs_mgr_is_checkpoint_fs(fstab_rec)) {
|
if (fstab_rec->fs_mgr_flags.checkpoint_fs) {
|
||||||
if (!strcmp(fstab_rec->fs_type, "f2fs")) {
|
if (fstab_rec->fs_type == "f2fs") {
|
||||||
std::string options = mount_rec->fs_options;
|
std::string options = mount_rec.fs_options + ",checkpoint=enable";
|
||||||
options += ",checkpoint=enable";
|
if (mount(mount_rec.blk_device.c_str(), mount_rec.mount_point.c_str(), "none",
|
||||||
if (mount(mount_rec->blk_device, mount_rec->mount_point, "none",
|
|
||||||
MS_REMOUNT | fstab_rec->flags, options.c_str())) {
|
MS_REMOUNT | fstab_rec->flags, options.c_str())) {
|
||||||
return Status::fromExceptionCode(EINVAL, "Failed to remount");
|
return Status::fromExceptionCode(EINVAL, "Failed to remount");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (fs_mgr_is_checkpoint_blk(fstab_rec)) {
|
} else if (fstab_rec->fs_mgr_flags.checkpoint_blk) {
|
||||||
if (!setBowState(mount_rec->blk_device, "2"))
|
if (!setBowState(mount_rec.blk_device, "2"))
|
||||||
return Status::fromExceptionCode(EINVAL, "Failed to set bow state");
|
return Status::fromExceptionCode(EINVAL, "Failed to set bow state");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,36 +197,36 @@ bool cp_needsCheckpoint() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Status cp_prepareCheckpoint() {
|
Status cp_prepareCheckpoint() {
|
||||||
auto fstab_default = std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)>{
|
Fstab fstab_default;
|
||||||
fs_mgr_read_fstab_default(), fs_mgr_free_fstab};
|
if (!ReadDefaultFstab(&fstab_default)) {
|
||||||
if (!fstab_default) return Status::fromExceptionCode(EINVAL, "Failed to get fstab");
|
return Status::fromExceptionCode(EINVAL, "Failed to get fstab");
|
||||||
|
}
|
||||||
|
|
||||||
auto mounts = std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)>{
|
Fstab mounts;
|
||||||
fs_mgr_read_fstab("/proc/mounts"), fs_mgr_free_fstab};
|
if (!ReadFstabFromFile("/proc/mounts", &mounts)) {
|
||||||
if (!mounts) return Status::fromExceptionCode(EINVAL, "Failed to get /proc/mounts");
|
return Status::fromExceptionCode(EINVAL, "Failed to get /proc/mounts");
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < mounts->num_entries; ++i) {
|
for (const auto& mount_rec : mounts) {
|
||||||
const fstab_rec* mount_rec = &mounts->recs[i];
|
const auto fstab_rec = GetEntryForMountPoint(&fstab_default, mount_rec.mount_point);
|
||||||
const fstab_rec* fstab_rec =
|
|
||||||
fs_mgr_get_entry_for_mount_point(fstab_default.get(), mount_rec->mount_point);
|
|
||||||
if (!fstab_rec) continue;
|
if (!fstab_rec) continue;
|
||||||
|
|
||||||
if (fs_mgr_is_checkpoint_blk(fstab_rec)) {
|
if (fstab_rec->fs_mgr_flags.checkpoint_blk) {
|
||||||
android::base::unique_fd fd(
|
android::base::unique_fd fd(
|
||||||
TEMP_FAILURE_RETRY(open(mount_rec->mount_point, O_RDONLY | O_CLOEXEC)));
|
TEMP_FAILURE_RETRY(open(mount_rec.mount_point.c_str(), O_RDONLY | O_CLOEXEC)));
|
||||||
if (!fd) {
|
if (!fd) {
|
||||||
PLOG(ERROR) << "Failed to open mount point" << mount_rec->mount_point;
|
PLOG(ERROR) << "Failed to open mount point" << mount_rec.mount_point;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fstrim_range range = {};
|
struct fstrim_range range = {};
|
||||||
range.len = ULLONG_MAX;
|
range.len = ULLONG_MAX;
|
||||||
if (ioctl(fd, FITRIM, &range)) {
|
if (ioctl(fd, FITRIM, &range)) {
|
||||||
PLOG(ERROR) << "Failed to trim " << mount_rec->mount_point;
|
PLOG(ERROR) << "Failed to trim " << mount_rec.mount_point;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
setBowState(mount_rec->blk_device, "1");
|
setBowState(mount_rec.blk_device, "1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Status::ok();
|
return Status::ok();
|
||||||
|
|
13
FsCrypt.cpp
13
FsCrypt.cpp
|
@ -61,6 +61,7 @@
|
||||||
|
|
||||||
using android::base::StringPrintf;
|
using android::base::StringPrintf;
|
||||||
using android::base::WriteStringToFile;
|
using android::base::WriteStringToFile;
|
||||||
|
using android::fs_mgr::GetEntryForMountPoint;
|
||||||
using android::vold::kEmptyAuthentication;
|
using android::vold::kEmptyAuthentication;
|
||||||
using android::vold::KeyBuffer;
|
using android::vold::KeyBuffer;
|
||||||
|
|
||||||
|
@ -276,12 +277,12 @@ static bool lookup_key_ref(const std::map<userid_t, std::string>& key_map, useri
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_data_file_encryption_modes(PolicyKeyRef* key_ref) {
|
static void get_data_file_encryption_modes(PolicyKeyRef* key_ref) {
|
||||||
struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab_default, DATA_MNT_POINT);
|
auto entry = GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT);
|
||||||
char const* contents_mode;
|
if (entry == nullptr) {
|
||||||
char const* filenames_mode;
|
return;
|
||||||
fs_mgr_get_file_encryption_modes(rec, &contents_mode, &filenames_mode);
|
}
|
||||||
key_ref->contents_mode = contents_mode;
|
key_ref->contents_mode = entry->file_contents_mode;
|
||||||
key_ref->filenames_mode = filenames_mode;
|
key_ref->filenames_mode = entry->file_names_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ensure_policy(const PolicyKeyRef& key_ref, const std::string& path) {
|
static bool ensure_policy(const PolicyKeyRef& key_ref, const std::string& path) {
|
||||||
|
|
|
@ -45,6 +45,8 @@ using android::base::Realpath;
|
||||||
using android::base::StringPrintf;
|
using android::base::StringPrintf;
|
||||||
using android::base::Timer;
|
using android::base::Timer;
|
||||||
using android::base::WriteStringToFile;
|
using android::base::WriteStringToFile;
|
||||||
|
using android::fs_mgr::Fstab;
|
||||||
|
using android::fs_mgr::ReadDefaultFstab;
|
||||||
using android::hardware::Return;
|
using android::hardware::Return;
|
||||||
using android::hardware::Void;
|
using android::hardware::Void;
|
||||||
using android::hardware::health::storage::V1_0::IGarbageCollectCallback;
|
using android::hardware::health::storage::V1_0::IGarbageCollectCallback;
|
||||||
|
@ -102,48 +104,43 @@ static void addFromVolumeManager(std::list<std::string>* paths, PathTypes path_t
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addFromFstab(std::list<std::string>* paths, PathTypes path_type) {
|
static void addFromFstab(std::list<std::string>* paths, PathTypes path_type) {
|
||||||
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
|
Fstab fstab;
|
||||||
fs_mgr_free_fstab);
|
ReadDefaultFstab(&fstab);
|
||||||
struct fstab_rec* prev_rec = NULL;
|
|
||||||
|
|
||||||
for (int i = 0; i < fstab->num_entries; i++) {
|
std::string previous_mount_point;
|
||||||
auto fs_type = std::string(fstab->recs[i].fs_type);
|
for (const auto& entry : fstab) {
|
||||||
/* Skip raw partitions */
|
// Skip raw partitions.
|
||||||
if (fs_type == "emmc" || fs_type == "mtd") {
|
if (entry.fs_type == "emmc" || entry.fs_type == "mtd") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* Skip read-only filesystems */
|
// Skip read-only filesystems
|
||||||
if (fstab->recs[i].flags & MS_RDONLY) {
|
if (entry.flags & MS_RDONLY) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (fs_mgr_is_voldmanaged(&fstab->recs[i])) {
|
if (entry.fs_mgr_flags.vold_managed) {
|
||||||
continue; /* Should we trim fat32 filesystems? */
|
continue; // Should we trim fat32 filesystems?
|
||||||
}
|
}
|
||||||
if (fs_mgr_is_notrim(&fstab->recs[i])) {
|
if (entry.fs_mgr_flags.no_trim) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip the multi-type partitions, which are required to be following each other.
|
// Skip the multi-type partitions, which are required to be following each other.
|
||||||
* See fs_mgr.c's mount_with_alternatives().
|
// See fs_mgr.c's mount_with_alternatives().
|
||||||
*/
|
if (entry.mount_point == previous_mount_point) {
|
||||||
if (prev_rec && !strcmp(prev_rec->mount_point, fstab->recs[i].mount_point)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path_type == PathTypes::kMountPoint) {
|
if (path_type == PathTypes::kMountPoint) {
|
||||||
paths->push_back(fstab->recs[i].mount_point);
|
paths->push_back(entry.mount_point);
|
||||||
} else if (path_type == PathTypes::kBlkDevice) {
|
} else if (path_type == PathTypes::kBlkDevice) {
|
||||||
std::string gc_path;
|
std::string gc_path;
|
||||||
if (std::string(fstab->recs[i].fs_type) == "f2fs" &&
|
if (entry.fs_type == "f2fs" &&
|
||||||
Realpath(
|
Realpath(android::vold::BlockDeviceForPath(entry.mount_point + "/"), &gc_path)) {
|
||||||
android::vold::BlockDeviceForPath(std::string(fstab->recs[i].mount_point) + "/"),
|
paths->push_back("/sys/fs/" + entry.fs_type + "/" + Basename(gc_path));
|
||||||
&gc_path)) {
|
|
||||||
paths->push_back(std::string("/sys/fs/") + fstab->recs[i].fs_type + "/" +
|
|
||||||
Basename(gc_path));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_rec = &fstab->recs[i];
|
previous_mount_point = entry.mount_point;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,22 +260,21 @@ static int stopGc(const std::list<std::string>& paths) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void runDevGcFstab(void) {
|
static void runDevGcFstab(void) {
|
||||||
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
|
Fstab fstab;
|
||||||
fs_mgr_free_fstab);
|
ReadDefaultFstab(&fstab);
|
||||||
struct fstab_rec* rec = NULL;
|
|
||||||
|
|
||||||
for (int i = 0; i < fstab->num_entries; i++) {
|
std::string path;
|
||||||
if (fs_mgr_has_sysfs_path(&fstab->recs[i])) {
|
for (const auto& entry : fstab) {
|
||||||
rec = &fstab->recs[i];
|
if (!entry.sysfs_path.empty()) {
|
||||||
|
path = entry.sysfs_path;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!rec) {
|
|
||||||
|
if (path.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string path;
|
|
||||||
path.append(rec->sysfs_path);
|
|
||||||
path = path + "/manual_gc";
|
path = path + "/manual_gc";
|
||||||
Timer timer;
|
Timer timer;
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,8 @@
|
||||||
#define TABLE_LOAD_RETRIES 10
|
#define TABLE_LOAD_RETRIES 10
|
||||||
#define DEFAULT_KEY_TARGET_TYPE "default-key"
|
#define DEFAULT_KEY_TARGET_TYPE "default-key"
|
||||||
|
|
||||||
|
using android::fs_mgr::FstabEntry;
|
||||||
|
using android::fs_mgr::GetEntryForMountPoint;
|
||||||
using android::vold::KeyBuffer;
|
using android::vold::KeyBuffer;
|
||||||
|
|
||||||
static const std::string kDmNameUserdata = "userdata";
|
static const std::string kDmNameUserdata = "userdata";
|
||||||
|
@ -63,7 +65,7 @@ static bool mount_via_fs_mgr(const char* mount_point, const char* blk_device) {
|
||||||
PLOG(ERROR) << "Failed to setexeccon";
|
PLOG(ERROR) << "Failed to setexeccon";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto mount_rc = fs_mgr_do_mount(fstab_default, const_cast<char*>(mount_point),
|
auto mount_rc = fs_mgr_do_mount(&fstab_default, const_cast<char*>(mount_point),
|
||||||
const_cast<char*>(blk_device), nullptr,
|
const_cast<char*>(blk_device), nullptr,
|
||||||
android::vold::cp_needsCheckpoint());
|
android::vold::cp_needsCheckpoint());
|
||||||
if (setexeccon(nullptr)) {
|
if (setexeccon(nullptr)) {
|
||||||
|
@ -106,12 +108,12 @@ static void commit_key(const std::string& dir) {
|
||||||
LOG(INFO) << "Old Key deleted: " << dir;
|
LOG(INFO) << "Old Key deleted: " << dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool read_key(struct fstab_rec const* data_rec, bool create_if_absent, KeyBuffer* key) {
|
static bool read_key(const FstabEntry& data_rec, bool create_if_absent, KeyBuffer* key) {
|
||||||
if (!data_rec->key_dir) {
|
if (data_rec.key_dir.empty()) {
|
||||||
LOG(ERROR) << "Failed to get key_dir";
|
LOG(ERROR) << "Failed to get key_dir";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string key_dir = data_rec->key_dir;
|
std::string key_dir = data_rec.key_dir;
|
||||||
std::string sKey;
|
std::string sKey;
|
||||||
auto dir = key_dir + "/key";
|
auto dir = key_dir + "/key";
|
||||||
LOG(DEBUG) << "key_dir/key: " << dir;
|
LOG(DEBUG) << "key_dir/key: " << dir;
|
||||||
|
@ -254,13 +256,14 @@ bool fscrypt_mount_metadata_encrypted(const std::string& mount_point, bool needs
|
||||||
LOG(DEBUG) << "fscrypt_enable_crypto got unexpected starting state: " << encrypted_state;
|
LOG(DEBUG) << "fscrypt_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);
|
|
||||||
|
auto data_rec = GetEntryForMountPoint(&fstab_default, mount_point);
|
||||||
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;
|
KeyBuffer key;
|
||||||
if (!read_key(data_rec, needs_encrypt, &key)) return false;
|
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;
|
||||||
|
@ -271,9 +274,8 @@ bool fscrypt_mount_metadata_encrypted(const std::string& mount_point, bool needs
|
||||||
if (needs_encrypt) {
|
if (needs_encrypt) {
|
||||||
LOG(INFO) << "Beginning inplace encryption, nr_sec: " << nr_sec;
|
LOG(INFO) << "Beginning inplace encryption, nr_sec: " << nr_sec;
|
||||||
off64_t size_already_done = 0;
|
off64_t size_already_done = 0;
|
||||||
auto rc =
|
auto rc = cryptfs_enable_inplace(crypto_blkdev.data(), data_rec->blk_device.data(), nr_sec,
|
||||||
cryptfs_enable_inplace(const_cast<char*>(crypto_blkdev.c_str()), data_rec->blk_device,
|
&size_already_done, nr_sec, 0, false);
|
||||||
nr_sec, &size_already_done, nr_sec, 0, false);
|
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
LOG(ERROR) << "Inplace crypto failed with code: " << rc;
|
LOG(ERROR) << "Inplace crypto failed with code: " << rc;
|
||||||
return false;
|
return false;
|
||||||
|
@ -286,6 +288,6 @@ bool fscrypt_mount_metadata_encrypted(const std::string& mount_point, bool needs
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(DEBUG) << "Mounting metadata-encrypted filesystem:" << mount_point;
|
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.c_str(), crypto_blkdev.c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/fs.h>
|
#include "VoldUtil.h"
|
||||||
#include <sys/ioctl.h>
|
|
||||||
|
|
||||||
struct fstab* fstab_default;
|
android::fs_mgr::Fstab fstab_default;
|
||||||
|
|
|
@ -14,14 +14,11 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _VOLDUTIL_H
|
#pragma once
|
||||||
#define _VOLDUTIL_H
|
|
||||||
|
|
||||||
#include <fstab/fstab.h>
|
#include <fstab/fstab.h>
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
extern struct fstab* fstab_default;
|
extern android::fs_mgr::Fstab fstab_default;
|
||||||
|
|
||||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
|
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
82
cryptfs.cpp
82
cryptfs.cpp
|
@ -77,6 +77,7 @@ extern "C" {
|
||||||
|
|
||||||
using android::base::ParseUint;
|
using android::base::ParseUint;
|
||||||
using android::base::StringPrintf;
|
using android::base::StringPrintf;
|
||||||
|
using android::fs_mgr::GetEntryForMountPoint;
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
#define UNUSED __attribute__((unused))
|
#define UNUSED __attribute__((unused))
|
||||||
|
@ -404,7 +405,7 @@ const char* cryptfs_get_crypto_name() {
|
||||||
return get_crypto_type().get_crypto_name();
|
return get_crypto_type().get_crypto_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t get_fs_size(char* dev) {
|
static uint64_t get_fs_size(const char* dev) {
|
||||||
int fd, block_size;
|
int fd, block_size;
|
||||||
struct ext4_super_block sb;
|
struct ext4_super_block sb;
|
||||||
uint64_t len;
|
uint64_t len;
|
||||||
|
@ -438,6 +439,22 @@ static uint64_t get_fs_size(char* dev) {
|
||||||
return len / 512;
|
return len / 512;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void get_crypt_info(std::string* key_loc, std::string* real_blk_device) {
|
||||||
|
for (const auto& entry : fstab_default) {
|
||||||
|
if (!entry.fs_mgr_flags.vold_managed &&
|
||||||
|
(entry.fs_mgr_flags.crypt || entry.fs_mgr_flags.force_crypt ||
|
||||||
|
entry.fs_mgr_flags.force_fde_or_fbe || entry.fs_mgr_flags.file_encryption)) {
|
||||||
|
if (key_loc != nullptr) {
|
||||||
|
*key_loc = entry.key_loc;
|
||||||
|
}
|
||||||
|
if (real_blk_device != nullptr) {
|
||||||
|
*real_blk_device = entry.blk_device;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int get_crypt_ftr_info(char** metadata_fname, off64_t* off) {
|
static int get_crypt_ftr_info(char** metadata_fname, off64_t* off) {
|
||||||
static int cached_data = 0;
|
static int cached_data = 0;
|
||||||
static uint64_t cached_off = 0;
|
static uint64_t cached_off = 0;
|
||||||
|
@ -447,22 +464,24 @@ static int get_crypt_ftr_info(char** metadata_fname, off64_t* off) {
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
|
|
||||||
if (!cached_data) {
|
if (!cached_data) {
|
||||||
fs_mgr_get_crypt_info(fstab_default, key_loc, real_blkdev, sizeof(key_loc));
|
std::string key_loc;
|
||||||
|
std::string real_blkdev;
|
||||||
|
get_crypt_info(&key_loc, &real_blkdev);
|
||||||
|
|
||||||
if (!strcmp(key_loc, KEY_IN_FOOTER)) {
|
if (key_loc == KEY_IN_FOOTER) {
|
||||||
if (android::vold::GetBlockDevSize(real_blkdev, &cached_off) == android::OK) {
|
if (android::vold::GetBlockDevSize(real_blkdev, &cached_off) == android::OK) {
|
||||||
/* If it's an encrypted Android partition, the last 16 Kbytes contain the
|
/* If it's an encrypted Android partition, the last 16 Kbytes contain the
|
||||||
* encryption info footer and key, and plenty of bytes to spare for future
|
* encryption info footer and key, and plenty of bytes to spare for future
|
||||||
* growth.
|
* growth.
|
||||||
*/
|
*/
|
||||||
strlcpy(cached_metadata_fname, real_blkdev, sizeof(cached_metadata_fname));
|
strlcpy(cached_metadata_fname, real_blkdev.c_str(), sizeof(cached_metadata_fname));
|
||||||
cached_off -= CRYPT_FOOTER_OFFSET;
|
cached_off -= CRYPT_FOOTER_OFFSET;
|
||||||
cached_data = 1;
|
cached_data = 1;
|
||||||
} else {
|
} else {
|
||||||
SLOGE("Cannot get size of block device %s\n", real_blkdev);
|
SLOGE("Cannot get size of block device %s\n", real_blkdev.c_str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
strlcpy(cached_metadata_fname, key_loc, sizeof(cached_metadata_fname));
|
strlcpy(cached_metadata_fname, key_loc.c_str(), sizeof(cached_metadata_fname));
|
||||||
cached_off = 0;
|
cached_off = 0;
|
||||||
cached_data = 1;
|
cached_data = 1;
|
||||||
}
|
}
|
||||||
|
@ -1595,9 +1614,9 @@ static int cryptfs_restart_internal(int restart_main) {
|
||||||
char ro_prop[PROPERTY_VALUE_MAX];
|
char ro_prop[PROPERTY_VALUE_MAX];
|
||||||
property_get("ro.crypto.readonly", ro_prop, "");
|
property_get("ro.crypto.readonly", ro_prop, "");
|
||||||
if (strlen(ro_prop) > 0 && std::stoi(ro_prop)) {
|
if (strlen(ro_prop) > 0 && std::stoi(ro_prop)) {
|
||||||
struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab_default, DATA_MNT_POINT);
|
auto entry = GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT);
|
||||||
if (rec) {
|
if (entry != nullptr) {
|
||||||
rec->flags |= MS_RDONLY;
|
entry->flags |= MS_RDONLY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1614,7 +1633,7 @@ static int cryptfs_restart_internal(int restart_main) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
bool needs_cp = android::vold::cp_needsCheckpoint();
|
bool needs_cp = android::vold::cp_needsCheckpoint();
|
||||||
while ((mount_rc = fs_mgr_do_mount(fstab_default, DATA_MNT_POINT, crypto_blkdev, 0,
|
while ((mount_rc = fs_mgr_do_mount(&fstab_default, DATA_MNT_POINT, crypto_blkdev, 0,
|
||||||
needs_cp)) != 0) {
|
needs_cp)) != 0) {
|
||||||
if (mount_rc == FS_MGR_DOMNT_BUSY) {
|
if (mount_rc == FS_MGR_DOMNT_BUSY) {
|
||||||
/* TODO: invoke something similar to
|
/* TODO: invoke something similar to
|
||||||
|
@ -1677,7 +1696,6 @@ int cryptfs_restart(void) {
|
||||||
static int do_crypto_complete(const char* mount_point) {
|
static int do_crypto_complete(const char* mount_point) {
|
||||||
struct crypt_mnt_ftr crypt_ftr;
|
struct crypt_mnt_ftr crypt_ftr;
|
||||||
char encrypted_state[PROPERTY_VALUE_MAX];
|
char encrypted_state[PROPERTY_VALUE_MAX];
|
||||||
char key_loc[PROPERTY_VALUE_MAX];
|
|
||||||
|
|
||||||
property_get("ro.crypto.state", encrypted_state, "");
|
property_get("ro.crypto.state", encrypted_state, "");
|
||||||
if (strcmp(encrypted_state, "encrypted")) {
|
if (strcmp(encrypted_state, "encrypted")) {
|
||||||
|
@ -1691,7 +1709,8 @@ static int do_crypto_complete(const char* mount_point) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_crypt_ftr_and_key(&crypt_ftr)) {
|
if (get_crypt_ftr_and_key(&crypt_ftr)) {
|
||||||
fs_mgr_get_crypt_info(fstab_default, key_loc, 0, sizeof(key_loc));
|
std::string key_loc;
|
||||||
|
get_crypt_info(&key_loc, nullptr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Only report this error if key_loc is a file and it exists.
|
* Only report this error if key_loc is a file and it exists.
|
||||||
|
@ -1700,7 +1719,7 @@ static int do_crypto_complete(const char* mount_point) {
|
||||||
* a "enter password" screen, or worse, a "press button to wipe the
|
* a "enter password" screen, or worse, a "press button to wipe the
|
||||||
* device" screen.
|
* device" screen.
|
||||||
*/
|
*/
|
||||||
if ((key_loc[0] == '/') && (access("key_loc", F_OK) == -1)) {
|
if (!key_loc.empty() && key_loc[0] == '/' && (access("key_loc", F_OK) == -1)) {
|
||||||
SLOGE("master key file does not exist, aborting");
|
SLOGE("master key file does not exist, aborting");
|
||||||
return CRYPTO_COMPLETE_NOT_ENCRYPTED;
|
return CRYPTO_COMPLETE_NOT_ENCRYPTED;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1733,7 +1752,7 @@ static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr, const char*
|
||||||
const char* mount_point, const char* label) {
|
const char* mount_point, const char* label) {
|
||||||
unsigned char decrypted_master_key[MAX_KEY_LEN];
|
unsigned char decrypted_master_key[MAX_KEY_LEN];
|
||||||
char crypto_blkdev[MAXPATHLEN];
|
char crypto_blkdev[MAXPATHLEN];
|
||||||
char real_blkdev[MAXPATHLEN];
|
std::string real_blkdev;
|
||||||
char tmp_mount_point[64];
|
char tmp_mount_point[64];
|
||||||
unsigned int orig_failed_decrypt_count;
|
unsigned int orig_failed_decrypt_count;
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -1757,12 +1776,12 @@ static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr, const char*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_mgr_get_crypt_info(fstab_default, 0, real_blkdev, sizeof(real_blkdev));
|
get_crypt_info(nullptr, &real_blkdev);
|
||||||
|
|
||||||
// Create crypto block device - all (non fatal) code paths
|
// Create crypto block device - all (non fatal) code paths
|
||||||
// need it
|
// need it
|
||||||
if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key, real_blkdev, crypto_blkdev, label,
|
if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key, real_blkdev.c_str(), crypto_blkdev,
|
||||||
0)) {
|
label, 0)) {
|
||||||
SLOGE("Error creating decrypted block device\n");
|
SLOGE("Error creating decrypted block device\n");
|
||||||
rc = -1;
|
rc = -1;
|
||||||
goto errout;
|
goto errout;
|
||||||
|
@ -1785,7 +1804,7 @@ static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr, const char*
|
||||||
* the footer, not the key. */
|
* the footer, not the key. */
|
||||||
snprintf(tmp_mount_point, sizeof(tmp_mount_point), "%s/tmp_mnt", mount_point);
|
snprintf(tmp_mount_point, sizeof(tmp_mount_point), "%s/tmp_mnt", mount_point);
|
||||||
mkdir(tmp_mount_point, 0755);
|
mkdir(tmp_mount_point, 0755);
|
||||||
if (fs_mgr_do_mount(fstab_default, DATA_MNT_POINT, crypto_blkdev, tmp_mount_point)) {
|
if (fs_mgr_do_mount(&fstab_default, DATA_MNT_POINT, crypto_blkdev, tmp_mount_point)) {
|
||||||
SLOGE("Error temp mounting decrypted block device\n");
|
SLOGE("Error temp mounting decrypted block device\n");
|
||||||
delete_crypto_blk_dev(label);
|
delete_crypto_blk_dev(label);
|
||||||
|
|
||||||
|
@ -2122,14 +2141,15 @@ static int vold_unmountAll(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
||||||
char crypto_blkdev[MAXPATHLEN], real_blkdev[MAXPATHLEN];
|
char crypto_blkdev[MAXPATHLEN];
|
||||||
|
std::string real_blkdev;
|
||||||
unsigned char decrypted_master_key[MAX_KEY_LEN];
|
unsigned char decrypted_master_key[MAX_KEY_LEN];
|
||||||
int rc = -1, i;
|
int rc = -1, i;
|
||||||
struct crypt_mnt_ftr crypt_ftr;
|
struct crypt_mnt_ftr crypt_ftr;
|
||||||
struct crypt_persist_data* pdata;
|
struct crypt_persist_data* pdata;
|
||||||
char encrypted_state[PROPERTY_VALUE_MAX];
|
char encrypted_state[PROPERTY_VALUE_MAX];
|
||||||
char lockid[32] = {0};
|
char lockid[32] = {0};
|
||||||
char key_loc[PROPERTY_VALUE_MAX];
|
std::string key_loc;
|
||||||
int num_vols;
|
int num_vols;
|
||||||
off64_t previously_encrypted_upto = 0;
|
off64_t previously_encrypted_upto = 0;
|
||||||
bool rebootEncryption = false;
|
bool rebootEncryption = false;
|
||||||
|
@ -2172,22 +2192,20 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
||||||
goto error_unencrypted;
|
goto error_unencrypted;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO refactor fs_mgr_get_crypt_info to get both in one call
|
get_crypt_info(&key_loc, &real_blkdev);
|
||||||
fs_mgr_get_crypt_info(fstab_default, key_loc, 0, sizeof(key_loc));
|
|
||||||
fs_mgr_get_crypt_info(fstab_default, 0, real_blkdev, sizeof(real_blkdev));
|
|
||||||
|
|
||||||
/* Get the size of the real block device */
|
/* Get the size of the real block device */
|
||||||
uint64_t nr_sec;
|
uint64_t nr_sec;
|
||||||
if (android::vold::GetBlockDev512Sectors(real_blkdev, &nr_sec) != android::OK) {
|
if (android::vold::GetBlockDev512Sectors(real_blkdev, &nr_sec) != android::OK) {
|
||||||
SLOGE("Cannot get size of block device %s\n", real_blkdev);
|
SLOGE("Cannot get size of block device %s\n", real_blkdev.c_str());
|
||||||
goto error_unencrypted;
|
goto error_unencrypted;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If doing inplace encryption, make sure the orig fs doesn't include the crypto footer */
|
/* If doing inplace encryption, make sure the orig fs doesn't include the crypto footer */
|
||||||
if (!strcmp(key_loc, KEY_IN_FOOTER)) {
|
if (key_loc == KEY_IN_FOOTER) {
|
||||||
uint64_t fs_size_sec, max_fs_size_sec;
|
uint64_t fs_size_sec, max_fs_size_sec;
|
||||||
fs_size_sec = get_fs_size(real_blkdev);
|
fs_size_sec = get_fs_size(real_blkdev.c_str());
|
||||||
if (fs_size_sec == 0) fs_size_sec = get_f2fs_filesystem_size_sec(real_blkdev);
|
if (fs_size_sec == 0) fs_size_sec = get_f2fs_filesystem_size_sec(real_blkdev.data());
|
||||||
|
|
||||||
max_fs_size_sec = nr_sec - (CRYPT_FOOTER_OFFSET / CRYPT_SECTOR_SIZE);
|
max_fs_size_sec = nr_sec - (CRYPT_FOOTER_OFFSET / CRYPT_SECTOR_SIZE);
|
||||||
|
|
||||||
|
@ -2260,7 +2278,7 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
||||||
goto error_shutting_down;
|
goto error_shutting_down;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(key_loc, KEY_IN_FOOTER)) {
|
if (key_loc == KEY_IN_FOOTER) {
|
||||||
crypt_ftr.fs_size = nr_sec - (CRYPT_FOOTER_OFFSET / CRYPT_SECTOR_SIZE);
|
crypt_ftr.fs_size = nr_sec - (CRYPT_FOOTER_OFFSET / CRYPT_SECTOR_SIZE);
|
||||||
} else {
|
} else {
|
||||||
crypt_ftr.fs_size = nr_sec;
|
crypt_ftr.fs_size = nr_sec;
|
||||||
|
@ -2330,7 +2348,7 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
||||||
}
|
}
|
||||||
|
|
||||||
decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr, 0, 0);
|
decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr, 0, 0);
|
||||||
create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev, crypto_blkdev,
|
create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev.c_str(), crypto_blkdev,
|
||||||
CRYPTO_BLOCK_DEVICE, 0);
|
CRYPTO_BLOCK_DEVICE, 0);
|
||||||
|
|
||||||
/* If we are continuing, check checksums match */
|
/* If we are continuing, check checksums match */
|
||||||
|
@ -2347,7 +2365,7 @@ int cryptfs_enable_internal(int crypt_type, const char* passwd, int no_ui) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
rc = cryptfs_enable_all_volumes(&crypt_ftr, crypto_blkdev, real_blkdev,
|
rc = cryptfs_enable_all_volumes(&crypt_ftr, crypto_blkdev, real_blkdev.data(),
|
||||||
previously_encrypted_upto);
|
previously_encrypted_upto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2893,6 +2911,6 @@ void cryptfs_clear_password() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int cryptfs_isConvertibleToFBE() {
|
int cryptfs_isConvertibleToFBE() {
|
||||||
struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab_default, DATA_MNT_POINT);
|
auto entry = GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT);
|
||||||
return (rec && fs_mgr_is_convertible_to_fbe(rec)) ? 1 : 0;
|
return entry && entry->fs_mgr_flags.force_fde_or_fbe;
|
||||||
}
|
}
|
||||||
|
|
23
main.cpp
23
main.cpp
|
@ -50,6 +50,7 @@ static void parse_args(int argc, char** argv);
|
||||||
struct selabel_handle* sehandle;
|
struct selabel_handle* sehandle;
|
||||||
|
|
||||||
using android::base::StringPrintf;
|
using android::base::StringPrintf;
|
||||||
|
using android::fs_mgr::ReadDefaultFstab;
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
atrace_set_tracing_enabled(false);
|
atrace_set_tracing_enabled(false);
|
||||||
|
@ -216,8 +217,7 @@ static int process_config(VolumeManager* vm, bool* has_adoptable, bool* has_quot
|
||||||
bool* has_reserved) {
|
bool* has_reserved) {
|
||||||
ATRACE_NAME("process_config");
|
ATRACE_NAME("process_config");
|
||||||
|
|
||||||
fstab_default = fs_mgr_read_fstab_default();
|
if (!ReadDefaultFstab(&fstab_default)) {
|
||||||
if (!fstab_default) {
|
|
||||||
PLOG(ERROR) << "Failed to open default fstab";
|
PLOG(ERROR) << "Failed to open default fstab";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -226,30 +226,29 @@ static int process_config(VolumeManager* vm, bool* has_adoptable, bool* has_quot
|
||||||
*has_adoptable = false;
|
*has_adoptable = false;
|
||||||
*has_quota = false;
|
*has_quota = false;
|
||||||
*has_reserved = false;
|
*has_reserved = false;
|
||||||
for (int i = 0; i < fstab_default->num_entries; i++) {
|
for (const auto& entry : fstab_default) {
|
||||||
auto rec = &fstab_default->recs[i];
|
if (entry.fs_mgr_flags.quota) {
|
||||||
if (fs_mgr_is_quota(rec)) {
|
|
||||||
*has_quota = true;
|
*has_quota = true;
|
||||||
}
|
}
|
||||||
if (rec->reserved_size > 0) {
|
if (entry.reserved_size > 0) {
|
||||||
*has_reserved = true;
|
*has_reserved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs_mgr_is_voldmanaged(rec)) {
|
if (entry.fs_mgr_flags.vold_managed) {
|
||||||
if (fs_mgr_is_nonremovable(rec)) {
|
if (entry.fs_mgr_flags.nonremovable) {
|
||||||
LOG(WARNING) << "nonremovable no longer supported; ignoring volume";
|
LOG(WARNING) << "nonremovable no longer supported; ignoring volume";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string sysPattern(rec->blk_device);
|
std::string sysPattern(entry.blk_device);
|
||||||
std::string nickname(rec->label);
|
std::string nickname(entry.label);
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
if (fs_mgr_is_encryptable(rec)) {
|
if (entry.is_encryptable()) {
|
||||||
flags |= android::vold::Disk::Flags::kAdoptable;
|
flags |= android::vold::Disk::Flags::kAdoptable;
|
||||||
*has_adoptable = true;
|
*has_adoptable = true;
|
||||||
}
|
}
|
||||||
if (fs_mgr_is_noemulatedsd(rec) ||
|
if (entry.fs_mgr_flags.no_emulated_sd ||
|
||||||
android::base::GetBoolProperty("vold.debug.default_primary", false)) {
|
android::base::GetBoolProperty("vold.debug.default_primary", false)) {
|
||||||
flags |= android::vold::Disk::Flags::kDefaultPrimary;
|
flags |= android::vold::Disk::Flags::kDefaultPrimary;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue