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:
Jeff Sharkey 2015-06-18 14:25:08 -07:00
parent 0417060e8e
commit bc40cc8f07
8 changed files with 59 additions and 10 deletions

View file

@ -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);

View file

@ -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();
} }

View file

@ -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

View file

@ -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

View file

@ -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;
} }

View file

@ -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 */

View file

@ -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) {

View file

@ -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);