OSDN Git Service

Add method to forget private partition keys.
authorJeff Sharkey <jsharkey@android.com>
Thu, 18 Jun 2015 21:25:08 +0000 (14:25 -0700)
committerJeff Sharkey <jsharkey@android.com>
Mon, 22 Jun 2015 21:04:54 +0000 (14:04 -0700)
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

CommandListener.cpp
Disk.cpp
Utils.cpp
Utils.h
VolumeBase.cpp
VolumeBase.h
VolumeManager.cpp
VolumeManager.h

index 5168de6..ee99479 100644 (file)
@@ -258,6 +258,11 @@ int CommandListener::VolumeCmd::runCommand(SocketClient *cli,
         nsecs_t res = vm->benchmarkVolume(id);
         return cli->sendMsg(ResponseCode::CommandOkay,
                 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);
index a536dbf..c680a43 100644 (file)
--- a/Disk.cpp
+++ b/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* kGptAndroidExpand = "193D1EA4-B3CA-11E4-B075-10604B889DCF";
 
-static const char* kKeyPath = "/data/misc/vold";
-
 enum class Table {
     kUnknown,
     kMbr,
@@ -126,10 +124,6 @@ status_t Disk::destroy() {
     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) {
     auto vol = std::shared_ptr<VolumeBase>(new PublicVolume(device));
     if (mJustPartitioned) {
@@ -147,13 +141,11 @@ void Disk::createPublicVolume(dev_t device) {
 }
 
 void Disk::createPrivateVolume(dev_t device, const std::string& partGuid) {
-    std::string tmp;
     std::string normalizedGuid;
-    if (HexToStr(partGuid, tmp)) {
+    if (NormalizeHex(partGuid, normalizedGuid)) {
         LOG(WARNING) << "Invalid GUID " << partGuid;
         return;
     }
-    StrToHex(tmp, normalizedGuid);
 
     std::string keyRaw;
     if (!ReadFileToString(BuildKeyPath(normalizedGuid), &keyRaw)) {
@@ -175,6 +167,7 @@ void Disk::createPrivateVolume(dev_t device, const std::string& partGuid) {
 
     mVolumes.push_back(vol);
     vol->setDiskId(getId());
+    vol->setPartGuid(partGuid);
     vol->create();
 }
 
index e06111a..2ccd45f 100644 (file)
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -52,6 +52,7 @@ security_context_t sFsckContext = nullptr;
 security_context_t sFsckUntrustedContext = nullptr;
 
 static const char* kBlkidPath = "/system/bin/blkid";
+static const char* kKeyPath = "/data/misc/vold";
 
 static const char* kProcFilesystems = "/proc/filesystems";
 
@@ -391,6 +392,14 @@ status_t StrToHex(const std::string& str, std::string& hex) {
     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) {
     struct statvfs sb;
     if (statvfs(path.c_str(), &sb) == 0) {
@@ -509,5 +518,9 @@ done:
     return res;
 }
 
+std::string BuildKeyPath(const std::string& partGuid) {
+    return StringPrintf("%s/expand_%s.key", kKeyPath, partGuid.c_str());
+}
+
 }  // namespace vold
 }  // namespace android
diff --git a/Utils.h b/Utils.h
index ab151aa..8d6bf38 100644 (file)
--- a/Utils.h
+++ b/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);
 /* Converts raw bytes to hex string */
 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 GetTreeBytes(const std::string& path);
@@ -86,6 +88,8 @@ bool IsFilesystemSupported(const std::string& fsType);
 /* Wipes contents of block device at given path */
 status_t WipeBlockDevice(const std::string& path);
 
+std::string BuildKeyPath(const std::string& partGuid);
+
 }  // namespace vold
 }  // namespace android
 
index 05a61ed..7d733cb 100644 (file)
@@ -59,6 +59,16 @@ status_t VolumeBase::setDiskId(const std::string& diskId) {
     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) {
     if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
         LOG(WARNING) << getId() << " flags change requires state unmounted or unmountable";
@@ -155,7 +165,8 @@ status_t VolumeBase::create() {
 
     mCreated = true;
     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);
     return res;
 }
index 42b4d65..d417019 100644 (file)
@@ -76,6 +76,7 @@ public:
 
     const std::string& getId() { return mId; }
     const std::string& getDiskId() { return mDiskId; }
+    const std::string& getPartGuid() { return mPartGuid; }
     Type getType() { return mType; }
     int getMountFlags() { return mMountFlags; }
     userid_t getMountUserId() { return mMountUserId; }
@@ -84,6 +85,7 @@ public:
     const std::string& getInternalPath() { return mInternalPath; }
 
     status_t setDiskId(const std::string& diskId);
+    status_t setPartGuid(const std::string& partGuid);
     status_t setMountFlags(int mountFlags);
     status_t setMountUserId(userid_t mountUserId);
     status_t setSilent(bool silent);
@@ -120,6 +122,8 @@ private:
     std::string mId;
     /* ID that uniquely references parent disk while alive */
     std::string mDiskId;
+    /* Partition GUID of this volume */
+    std::string mPartGuid;
     /* Volume type */
     Type mType;
     /* Flags used when mounting this volume */
index 6f783a2..f1667f2 100755 (executable)
@@ -59,6 +59,7 @@
 #include "Asec.h"
 #include "VoldUtil.h"
 #include "cryptfs.h"
+#include "fstrim.h"
 
 #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);
 }
 
+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) {
     std::string source(mPrimary->getPath());
     if (mPrimary->getType() == android::vold::VolumeBase::Type::kEmulated) {
index 3207de8..8620d25 100644 (file)
@@ -120,6 +120,8 @@ public:
 
     nsecs_t benchmarkVolume(const std::string& id);
 
+    int forgetPartition(const std::string& partGuid);
+
     int onUserAdded(userid_t userId, int userSerialNumber);
     int onUserRemoved(userid_t userId);
     int onUserStarted(userid_t userId);