Add method to forget private partition keys.
Report both the disk and the partition GUID for private volumes to userspace, and offer to forget the encryption key for a given partition GUID. Bug: 21782268 Change-Id: Ie77a3a58e47bf3563cdb3e4b0edfab1de4d0e6b4
This commit is contained in:
parent
0417060e8e
commit
bc40cc8f07
8 changed files with 59 additions and 10 deletions
|
@ -258,6 +258,11 @@ int CommandListener::VolumeCmd::runCommand(SocketClient *cli,
|
||||||
nsecs_t res = vm->benchmarkVolume(id);
|
nsecs_t res = vm->benchmarkVolume(id);
|
||||||
return cli->sendMsg(ResponseCode::CommandOkay,
|
return cli->sendMsg(ResponseCode::CommandOkay,
|
||||||
android::base::StringPrintf("%" PRId64, res).c_str(), false);
|
android::base::StringPrintf("%" PRId64, res).c_str(), false);
|
||||||
|
|
||||||
|
} else if (cmd == "forget_partition" && argc > 2) {
|
||||||
|
// forget_partition [partGuid]
|
||||||
|
std::string partGuid(argv[2]);
|
||||||
|
return sendGenericOkFail(cli, vm->forgetPartition(partGuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
return cli->sendMsg(ResponseCode::CommandSyntaxError, nullptr, false);
|
return cli->sendMsg(ResponseCode::CommandSyntaxError, nullptr, false);
|
||||||
|
|
11
Disk.cpp
11
Disk.cpp
|
@ -72,8 +72,6 @@ static const char* kGptBasicData = "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7";
|
||||||
static const char* kGptAndroidMeta = "19A710A2-B3CA-11E4-B026-10604B889DCF";
|
static const char* kGptAndroidMeta = "19A710A2-B3CA-11E4-B026-10604B889DCF";
|
||||||
static const char* kGptAndroidExpand = "193D1EA4-B3CA-11E4-B075-10604B889DCF";
|
static const char* kGptAndroidExpand = "193D1EA4-B3CA-11E4-B075-10604B889DCF";
|
||||||
|
|
||||||
static const char* kKeyPath = "/data/misc/vold";
|
|
||||||
|
|
||||||
enum class Table {
|
enum class Table {
|
||||||
kUnknown,
|
kUnknown,
|
||||||
kMbr,
|
kMbr,
|
||||||
|
@ -126,10 +124,6 @@ status_t Disk::destroy() {
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string BuildKeyPath(const std::string& partGuid) {
|
|
||||||
return StringPrintf("%s/expand_%s.key", kKeyPath, partGuid.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Disk::createPublicVolume(dev_t device) {
|
void Disk::createPublicVolume(dev_t device) {
|
||||||
auto vol = std::shared_ptr<VolumeBase>(new PublicVolume(device));
|
auto vol = std::shared_ptr<VolumeBase>(new PublicVolume(device));
|
||||||
if (mJustPartitioned) {
|
if (mJustPartitioned) {
|
||||||
|
@ -147,13 +141,11 @@ void Disk::createPublicVolume(dev_t device) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Disk::createPrivateVolume(dev_t device, const std::string& partGuid) {
|
void Disk::createPrivateVolume(dev_t device, const std::string& partGuid) {
|
||||||
std::string tmp;
|
|
||||||
std::string normalizedGuid;
|
std::string normalizedGuid;
|
||||||
if (HexToStr(partGuid, tmp)) {
|
if (NormalizeHex(partGuid, normalizedGuid)) {
|
||||||
LOG(WARNING) << "Invalid GUID " << partGuid;
|
LOG(WARNING) << "Invalid GUID " << partGuid;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
StrToHex(tmp, normalizedGuid);
|
|
||||||
|
|
||||||
std::string keyRaw;
|
std::string keyRaw;
|
||||||
if (!ReadFileToString(BuildKeyPath(normalizedGuid), &keyRaw)) {
|
if (!ReadFileToString(BuildKeyPath(normalizedGuid), &keyRaw)) {
|
||||||
|
@ -175,6 +167,7 @@ void Disk::createPrivateVolume(dev_t device, const std::string& partGuid) {
|
||||||
|
|
||||||
mVolumes.push_back(vol);
|
mVolumes.push_back(vol);
|
||||||
vol->setDiskId(getId());
|
vol->setDiskId(getId());
|
||||||
|
vol->setPartGuid(partGuid);
|
||||||
vol->create();
|
vol->create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
Utils.cpp
13
Utils.cpp
|
@ -52,6 +52,7 @@ security_context_t sFsckContext = nullptr;
|
||||||
security_context_t sFsckUntrustedContext = nullptr;
|
security_context_t sFsckUntrustedContext = nullptr;
|
||||||
|
|
||||||
static const char* kBlkidPath = "/system/bin/blkid";
|
static const char* kBlkidPath = "/system/bin/blkid";
|
||||||
|
static const char* kKeyPath = "/data/misc/vold";
|
||||||
|
|
||||||
static const char* kProcFilesystems = "/proc/filesystems";
|
static const char* kProcFilesystems = "/proc/filesystems";
|
||||||
|
|
||||||
|
@ -391,6 +392,14 @@ status_t StrToHex(const std::string& str, std::string& hex) {
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t NormalizeHex(const std::string& in, std::string& out) {
|
||||||
|
std::string tmp;
|
||||||
|
if (HexToStr(in, tmp)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return StrToHex(tmp, out);
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t GetFreeBytes(const std::string& path) {
|
uint64_t GetFreeBytes(const std::string& path) {
|
||||||
struct statvfs sb;
|
struct statvfs sb;
|
||||||
if (statvfs(path.c_str(), &sb) == 0) {
|
if (statvfs(path.c_str(), &sb) == 0) {
|
||||||
|
@ -509,5 +518,9 @@ done:
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string BuildKeyPath(const std::string& partGuid) {
|
||||||
|
return StringPrintf("%s/expand_%s.key", kKeyPath, partGuid.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace vold
|
} // namespace vold
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
4
Utils.h
4
Utils.h
|
@ -77,6 +77,8 @@ status_t ReadRandomBytes(size_t bytes, std::string& out);
|
||||||
status_t HexToStr(const std::string& hex, std::string& str);
|
status_t HexToStr(const std::string& hex, std::string& str);
|
||||||
/* Converts raw bytes to hex string */
|
/* Converts raw bytes to hex string */
|
||||||
status_t StrToHex(const std::string& str, std::string& hex);
|
status_t StrToHex(const std::string& str, std::string& hex);
|
||||||
|
/* Normalize given hex string into consistent format */
|
||||||
|
status_t NormalizeHex(const std::string& in, std::string& out);
|
||||||
|
|
||||||
uint64_t GetFreeBytes(const std::string& path);
|
uint64_t GetFreeBytes(const std::string& path);
|
||||||
uint64_t GetTreeBytes(const std::string& path);
|
uint64_t GetTreeBytes(const std::string& path);
|
||||||
|
@ -86,6 +88,8 @@ bool IsFilesystemSupported(const std::string& fsType);
|
||||||
/* Wipes contents of block device at given path */
|
/* Wipes contents of block device at given path */
|
||||||
status_t WipeBlockDevice(const std::string& path);
|
status_t WipeBlockDevice(const std::string& path);
|
||||||
|
|
||||||
|
std::string BuildKeyPath(const std::string& partGuid);
|
||||||
|
|
||||||
} // namespace vold
|
} // namespace vold
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,16 @@ status_t VolumeBase::setDiskId(const std::string& diskId) {
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t VolumeBase::setPartGuid(const std::string& partGuid) {
|
||||||
|
if (mCreated) {
|
||||||
|
LOG(WARNING) << getId() << " partGuid change requires destroyed";
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
mPartGuid = partGuid;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
status_t VolumeBase::setMountFlags(int mountFlags) {
|
status_t VolumeBase::setMountFlags(int mountFlags) {
|
||||||
if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
|
if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
|
||||||
LOG(WARNING) << getId() << " flags change requires state unmounted or unmountable";
|
LOG(WARNING) << getId() << " flags change requires state unmounted or unmountable";
|
||||||
|
@ -155,7 +165,8 @@ status_t VolumeBase::create() {
|
||||||
|
|
||||||
mCreated = true;
|
mCreated = true;
|
||||||
status_t res = doCreate();
|
status_t res = doCreate();
|
||||||
notifyEvent(ResponseCode::VolumeCreated, StringPrintf("%d %s", mType, mDiskId.c_str()));
|
notifyEvent(ResponseCode::VolumeCreated,
|
||||||
|
StringPrintf("%d \"%s\" \"%s\"", mType, mDiskId.c_str(), mPartGuid.c_str()));
|
||||||
setState(State::kUnmounted);
|
setState(State::kUnmounted);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,7 @@ public:
|
||||||
|
|
||||||
const std::string& getId() { return mId; }
|
const std::string& getId() { return mId; }
|
||||||
const std::string& getDiskId() { return mDiskId; }
|
const std::string& getDiskId() { return mDiskId; }
|
||||||
|
const std::string& getPartGuid() { return mPartGuid; }
|
||||||
Type getType() { return mType; }
|
Type getType() { return mType; }
|
||||||
int getMountFlags() { return mMountFlags; }
|
int getMountFlags() { return mMountFlags; }
|
||||||
userid_t getMountUserId() { return mMountUserId; }
|
userid_t getMountUserId() { return mMountUserId; }
|
||||||
|
@ -84,6 +85,7 @@ public:
|
||||||
const std::string& getInternalPath() { return mInternalPath; }
|
const std::string& getInternalPath() { return mInternalPath; }
|
||||||
|
|
||||||
status_t setDiskId(const std::string& diskId);
|
status_t setDiskId(const std::string& diskId);
|
||||||
|
status_t setPartGuid(const std::string& partGuid);
|
||||||
status_t setMountFlags(int mountFlags);
|
status_t setMountFlags(int mountFlags);
|
||||||
status_t setMountUserId(userid_t mountUserId);
|
status_t setMountUserId(userid_t mountUserId);
|
||||||
status_t setSilent(bool silent);
|
status_t setSilent(bool silent);
|
||||||
|
@ -120,6 +122,8 @@ private:
|
||||||
std::string mId;
|
std::string mId;
|
||||||
/* ID that uniquely references parent disk while alive */
|
/* ID that uniquely references parent disk while alive */
|
||||||
std::string mDiskId;
|
std::string mDiskId;
|
||||||
|
/* Partition GUID of this volume */
|
||||||
|
std::string mPartGuid;
|
||||||
/* Volume type */
|
/* Volume type */
|
||||||
Type mType;
|
Type mType;
|
||||||
/* Flags used when mounting this volume */
|
/* Flags used when mounting this volume */
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
#include "Asec.h"
|
#include "Asec.h"
|
||||||
#include "VoldUtil.h"
|
#include "VoldUtil.h"
|
||||||
#include "cryptfs.h"
|
#include "cryptfs.h"
|
||||||
|
#include "fstrim.h"
|
||||||
|
|
||||||
#define MASS_STORAGE_FILE_PATH "/sys/class/android_usb/android0/f_mass_storage/lun/file"
|
#define MASS_STORAGE_FILE_PATH "/sys/class/android_usb/android0/f_mass_storage/lun/file"
|
||||||
|
|
||||||
|
@ -405,6 +406,22 @@ nsecs_t VolumeManager::benchmarkVolume(const std::string& id) {
|
||||||
return android::vold::Benchmark(path, sysPath);
|
return android::vold::Benchmark(path, sysPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int VolumeManager::forgetPartition(const std::string& partGuid) {
|
||||||
|
std::string normalizedGuid;
|
||||||
|
if (android::vold::NormalizeHex(partGuid, normalizedGuid)) {
|
||||||
|
LOG(WARNING) << "Invalid GUID " << partGuid;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string keyPath = android::vold::BuildKeyPath(normalizedGuid);
|
||||||
|
if (unlink(keyPath.c_str()) != 0) {
|
||||||
|
LOG(ERROR) << "Failed to unlink " << keyPath;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int VolumeManager::linkPrimary(userid_t userId) {
|
int VolumeManager::linkPrimary(userid_t userId) {
|
||||||
std::string source(mPrimary->getPath());
|
std::string source(mPrimary->getPath());
|
||||||
if (mPrimary->getType() == android::vold::VolumeBase::Type::kEmulated) {
|
if (mPrimary->getType() == android::vold::VolumeBase::Type::kEmulated) {
|
||||||
|
|
|
@ -120,6 +120,8 @@ public:
|
||||||
|
|
||||||
nsecs_t benchmarkVolume(const std::string& id);
|
nsecs_t benchmarkVolume(const std::string& id);
|
||||||
|
|
||||||
|
int forgetPartition(const std::string& partGuid);
|
||||||
|
|
||||||
int onUserAdded(userid_t userId, int userSerialNumber);
|
int onUserAdded(userid_t userId, int userSerialNumber);
|
||||||
int onUserRemoved(userid_t userId);
|
int onUserRemoved(userid_t userId);
|
||||||
int onUserStarted(userid_t userId);
|
int onUserStarted(userid_t userId);
|
||||||
|
|
Loading…
Reference in a new issue