From 0de365fc0af30ae48c2037e1057f2a813029a618 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Wed, 16 Oct 2013 16:24:19 -0700 Subject: [PATCH] Extract UUID and label from inserted volumes. Uses "blkid" tool to extract metadata from an inserted volume, and reports it up to the framework. This needs to happen in vold, since only the FUSE-wrapped volume is visible to userspace. Remove autorun sanitization, since FUSE takes care of this now. Bug: 11175082 Change-Id: Ie69b38011ad6011bfb50e40d4f35a29e02150c19 --- Android.mk | 3 ++ ResponseCode.h | 2 + Volume.cpp | 124 ++++++++++++++++++++++++++++++++++++++++--------- Volume.h | 14 ++++-- 4 files changed, 118 insertions(+), 25 deletions(-) diff --git a/Android.mk b/Android.mk index 8d0b249..cecab1e 100644 --- a/Android.mk +++ b/Android.mk @@ -23,10 +23,13 @@ common_c_includes := \ $(KERNEL_HEADERS) \ system/extras/ext4_utils \ external/openssl/include \ + external/stlport/stlport \ + bionic \ external/scrypt/lib/crypto common_shared_libraries := \ libsysutils \ + libstlport \ libcutils \ liblog \ libdiskconfig \ diff --git a/ResponseCode.h b/ResponseCode.h index dccacb8..5e4c6fa 100644 --- a/ResponseCode.h +++ b/ResponseCode.h @@ -57,6 +57,8 @@ public: static const int VolumeMountFailedBlank = 610; static const int VolumeMountFailedDamaged = 611; static const int VolumeMountFailedNoMedia = 612; + static const int VolumeUuidChange = 613; + static const int VolumeUserLabelChange = 614; static const int ShareAvailabilityChange = 620; diff --git a/Volume.cpp b/Volume.cpp index 7d33919..cbec5d4 100644 --- a/Volume.cpp +++ b/Volume.cpp @@ -40,6 +40,8 @@ #include #include +#include + #include "Volume.h" #include "VolumeManager.h" #include "ResponseCode.h" @@ -80,6 +82,8 @@ const char *Volume::ASECDIR = "/mnt/asec"; */ const char *Volume::LOOPDIR = "/mnt/obb"; +const char *Volume::BLKID_PATH = "/system/bin/blkid"; + static const char *stateToStr(int state) { if (state == Volume::State_Init) return "Initializing"; @@ -109,6 +113,8 @@ Volume::Volume(VolumeManager *vm, const fstab_rec* rec, int flags) { mVm = vm; mDebug = false; mLabel = strdup(rec->label); + mUuid = NULL; + mUserLabel = NULL; mState = Volume::State_Init; mFlags = flags; mCurrentlyMountedKdev = -1; @@ -118,25 +124,8 @@ Volume::Volume(VolumeManager *vm, const fstab_rec* rec, int flags) { Volume::~Volume() { free(mLabel); -} - -void Volume::protectFromAutorunStupidity() { - char filename[255]; - - snprintf(filename, sizeof(filename), "%s/autorun.inf", getMountpoint()); - if (!access(filename, F_OK)) { - SLOGW("Volume contains an autorun.inf! - removing"); - /* - * Ensure the filename is all lower-case so - * the process killer can find the inode. - * Probably being paranoid here but meh. - */ - rename(filename, filename); - Process::killProcessesWithOpenFiles(filename, 2); - if (unlink(filename)) { - SLOGE("Failed to remove %s (%s)", filename, strerror(errno)); - } - } + free(mUuid); + free(mUserLabel); } void Volume::setDebug(bool enable) { @@ -162,6 +151,46 @@ int Volume::handleBlockEvent(NetlinkEvent *evt) { return -1; } +void Volume::setUuid(const char* uuid) { + char msg[256]; + + if (mUuid) { + free(mUuid); + } + + if (uuid) { + mUuid = strdup(uuid); + snprintf(msg, sizeof(msg), "%s %s \"%s\"", getLabel(), + getFuseMountpoint(), mUuid); + } else { + mUuid = NULL; + snprintf(msg, sizeof(msg), "%s %s", getLabel(), getFuseMountpoint()); + } + + mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeUuidChange, msg, + false); +} + +void Volume::setUserLabel(const char* userLabel) { + char msg[256]; + + if (mUserLabel) { + free(mUserLabel); + } + + if (userLabel) { + mUserLabel = strdup(userLabel); + snprintf(msg, sizeof(msg), "%s %s \"%s\"", getLabel(), + getFuseMountpoint(), mUserLabel); + } else { + mUserLabel = NULL; + snprintf(msg, sizeof(msg), "%s %s", getLabel(), getFuseMountpoint()); + } + + mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeUserLabelChange, + msg, false); +} + void Volume::setState(int state) { char msg[255]; int oldState = mState; @@ -274,7 +303,6 @@ bool Volume::isMountpointMounted(const char *path) { fclose(fp); return true; } - } fclose(fp); @@ -413,7 +441,7 @@ int Volume::mountVol() { continue; } - protectFromAutorunStupidity(); + extractMetadata(devicePath); if (providesAsec && mountAsecExternal() != 0) { SLOGE("Failed to mount secure area (%s)", strerror(errno)); @@ -550,6 +578,8 @@ int Volume::unmountVol(bool force, bool revert) { SLOGI("Encrypted volume %s reverted successfully", getMountpoint()); } + setUuid(NULL); + setUserLabel(NULL); setState(Volume::State_Idle); mCurrentlyMountedKdev = -1; return 0; @@ -608,3 +638,55 @@ int Volume::initializeMbr(const char *deviceNode) { return rc; } + +/* + * Use blkid to extract UUID and label from device, since it handles many + * obscure edge cases around partition types and formats. Always broadcasts + * updated metadata values. + */ +int Volume::extractMetadata(const char* devicePath) { + int res = 0; + + std::string cmd; + cmd = BLKID_PATH; + cmd += " -c /dev/null "; + cmd += devicePath; + + FILE* fp = popen(cmd.c_str(), "r"); + if (!fp) { + ALOGE("Failed to run %s: %s", cmd.c_str(), strerror(errno)); + res = -1; + goto done; + } + + char line[1024]; + char value[128]; + if (fgets(line, sizeof(line), fp) != NULL) { + ALOGD("blkid reported: %s", line); + + char* start = strstr(line, "UUID=") + 5; + if (sscanf(start, "\"%127[^\"]\"", value) == 1) { + setUuid(value); + } else { + setUuid(NULL); + } + + start = strstr(line, "LABEL=") + 6; + if (sscanf(start, "\"%127[^\"]\"", value) == 1) { + setUserLabel(value); + } else { + setUserLabel(NULL); + } + } else { + res = -1; + } + + pclose(fp); + +done: + if (res == -1) { + setUuid(NULL); + setUserLabel(NULL); + } + return res; +} diff --git a/Volume.h b/Volume.h index 194004c..1444ed3 100644 --- a/Volume.h +++ b/Volume.h @@ -45,11 +45,13 @@ public: static const char *SEC_ASECDIR_EXT; static const char *SEC_ASECDIR_INT; static const char *ASECDIR; - static const char *LOOPDIR; + static const char *BLKID_PATH; protected: - char *mLabel; + char* mLabel; + char* mUuid; + char* mUserLabel; VolumeManager *mVm; bool mDebug; int mPartIdx; @@ -69,7 +71,9 @@ public: int unmountVol(bool force, bool revert); int formatVol(bool wipe); - const char *getLabel() { return mLabel; } + const char* getLabel() { return mLabel; } + const char* getUuid() { return mUuid; } + const char* getUserLabel() { return mUserLabel; } int getState() { return mState; } int getFlags() { return mFlags; }; @@ -87,6 +91,8 @@ public: virtual int getVolInfo(struct volume_info *v) = 0; protected: + void setUuid(const char* uuid); + void setUserLabel(const char* userLabel); void setState(int state); virtual int getDeviceNodes(dev_t *devs, int max) = 0; @@ -101,7 +107,7 @@ private: bool isMountpointMounted(const char *path); int mountAsecExternal(); int doUnmount(const char *path, bool force); - void protectFromAutorunStupidity(); + int extractMetadata(const char* devicePath); }; typedef android::List VolumeCollection;