summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DirectVolume.cpp22
-rw-r--r--VolumeManager.cpp74
-rw-r--r--VolumeManager.h2
-rw-r--r--cryptfs.c9
4 files changed, 97 insertions, 10 deletions
diff --git a/DirectVolume.cpp b/DirectVolume.cpp
index 4acee76..2a24376 100644
--- a/DirectVolume.cpp
+++ b/DirectVolume.cpp
@@ -113,6 +113,16 @@ int DirectVolume::handleBlockEvent(NetlinkEvent *evt) {
} else {
handlePartitionAdded(dp, evt);
}
+ /* Send notification iff disk is ready (ie all partitions found) */
+ if (getState() == Volume::State_Idle) {
+ char msg[255];
+
+ snprintf(msg, sizeof(msg),
+ "Volume %s %s disk inserted (%d:%d)", getLabel(),
+ getMountpoint(), mDiskMajor, mDiskMinor);
+ mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeDiskInserted,
+ msg, false);
+ }
} else if (action == NetlinkEvent::NlActionRemove) {
if (!strcmp(devtype, "disk")) {
handleDiskRemoved(dp, evt);
@@ -148,8 +158,6 @@ void DirectVolume::handleDiskAdded(const char *devpath, NetlinkEvent *evt) {
mDiskNumParts = 1;
}
- char msg[255];
-
int partmask = 0;
int i;
for (i = 1; i <= mDiskNumParts; i++) {
@@ -169,11 +177,6 @@ void DirectVolume::handleDiskAdded(const char *devpath, NetlinkEvent *evt) {
#endif
setState(Volume::State_Pending);
}
-
- snprintf(msg, sizeof(msg), "Volume %s %s disk inserted (%d:%d)",
- getLabel(), getMountpoint(), mDiskMajor, mDiskMinor);
- mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeDiskInserted,
- msg, false);
}
void DirectVolume::handlePartitionAdded(const char *devpath, NetlinkEvent *evt) {
@@ -275,6 +278,11 @@ void DirectVolume::handleDiskRemoved(const char *devpath, NetlinkEvent *evt) {
int major = atoi(evt->findParam("MAJOR"));
int minor = atoi(evt->findParam("MINOR"));
char msg[255];
+ bool enabled;
+
+ if (mVm->shareEnabled(getLabel(), "ums", &enabled) == 0 && enabled) {
+ mVm->unshareVolume(getLabel(), "ums");
+ }
SLOGD("Volume %s %s disk %d:%d removed\n", getLabel(), getMountpoint(), major, minor);
snprintf(msg, sizeof(msg), "Volume %s %s disk removed (%d:%d)",
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 3a63a19..1c48932 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -24,6 +24,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mount.h>
+#include <dirent.h>
#include <linux/kdev_t.h>
@@ -570,8 +571,8 @@ int VolumeManager::fixupAsecPermissions(const char *id, gid_t gid, const char* f
result |= fchown(fd, AID_SYSTEM, privateFile? gid : AID_SYSTEM);
if (ftsent->fts_info & FTS_D) {
- result |= fchmod(fd, 0711);
- } else {
+ result |= fchmod(fd, 0755);
+ } else if (ftsent->fts_info & FTS_F) {
result |= fchmod(fd, privateFile ? 0640 : 0644);
}
close(fd);
@@ -948,6 +949,19 @@ int VolumeManager::mountAsec(const char *id, const char *key, int ownerUid) {
}
}
+ /*
+ * The device mapper node needs to be created. Sometimes it takes a
+ * while. Wait for up to 1 second. We could also inspect incoming uevents,
+ * but that would take more effort.
+ */
+ int tries = 25;
+ while (tries--) {
+ if (!access(dmDevice, F_OK) || errno != ENOENT) {
+ break;
+ }
+ usleep(40 * 1000);
+ }
+
int result;
if (sb.c_opts & ASEC_SB_C_OPTS_EXT4) {
result = Ext4::doMount(dmDevice, mountPoint, true, false, true);
@@ -1347,6 +1361,62 @@ int VolumeManager::unmountVolume(const char *label, bool force, bool revert) {
return v->unmountVol(force, revert);
}
+extern "C" int vold_unmountAllAsecs(void) {
+ int rc;
+
+ VolumeManager *vm = VolumeManager::Instance();
+ rc = vm->unmountAllAsecsInDir(Volume::SEC_ASECDIR_EXT);
+ if (vm->unmountAllAsecsInDir(Volume::SEC_ASECDIR_INT)) {
+ rc = -1;
+ }
+ return rc;
+}
+
+#define ID_BUF_LEN 256
+#define ASEC_SUFFIX ".asec"
+#define ASEC_SUFFIX_LEN (sizeof(ASEC_SUFFIX) - 1)
+int VolumeManager::unmountAllAsecsInDir(const char *directory) {
+ DIR *d = opendir(directory);
+ int rc = 0;
+
+ if (!d) {
+ SLOGE("Could not open asec dir %s", directory);
+ return -1;
+ }
+
+ size_t dirent_len = offsetof(struct dirent, d_name) +
+ pathconf(directory, _PC_NAME_MAX) + 1;
+
+ struct dirent *dent = (struct dirent *) malloc(dirent_len);
+ if (dent == NULL) {
+ SLOGE("Failed to allocate memory for asec dir");
+ return -1;
+ }
+
+ struct dirent *result;
+ while (!readdir_r(d, dent, &result) && result != NULL) {
+ if (dent->d_name[0] == '.')
+ continue;
+ if (dent->d_type != DT_REG)
+ continue;
+ size_t name_len = strlen(dent->d_name);
+ if (name_len > 5 && name_len < (ID_BUF_LEN + ASEC_SUFFIX_LEN - 1) &&
+ !strcmp(&dent->d_name[name_len - 5], ASEC_SUFFIX)) {
+ char id[ID_BUF_LEN];
+ strlcpy(id, dent->d_name, name_len - 4);
+ if (unmountAsec(id, true)) {
+ /* Register the error, but try to unmount more asecs */
+ rc = -1;
+ }
+ }
+ }
+ closedir(d);
+
+ free(dent);
+
+ return rc;
+}
+
/*
* Looks up a volume by it's label or mount-point
*/
diff --git a/VolumeManager.h b/VolumeManager.h
index 3802503..4399b76 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -136,6 +136,7 @@ public:
Volume *lookupVolume(const char *label);
int getNumDirectVolumes(void);
int getDirectVolumeList(struct volume_info *vol_list);
+ int unmountAllAsecsInDir(const char *directory);
private:
VolumeManager();
@@ -150,6 +151,7 @@ extern "C" {
int vold_disableVol(const char *label);
int vold_getNumDirectVolumes(void);
int vold_getDirectVolumeList(struct volume_info *v);
+ int vold_unmountAllAsecs(void);
#ifdef __cplusplus
}
#endif
diff --git a/cryptfs.c b/cryptfs.c
index 094016c..cebe625 100644
--- a/cryptfs.c
+++ b/cryptfs.c
@@ -1214,6 +1214,13 @@ int cryptfs_enable(char *howarg, char *passwd)
property_set("vold.decrypt", "trigger_shutdown_framework");
SLOGD("Just asked init to shut down class main\n");
+ if (vold_unmountAllAsecs()) {
+ /* Just report the error. If any are left mounted,
+ * umounting /data below will fail and handle the error.
+ */
+ SLOGE("Error unmounting internal asecs");
+ }
+
property_get("ro.crypto.fuse_sdcard", fuse_sdcard, "");
if (!strcmp(fuse_sdcard, "true")) {
/* This is a device using the fuse layer to emulate the sdcard semantics
@@ -1363,7 +1370,7 @@ int cryptfs_enable(char *howarg, char *passwd)
/* wipe data if encryption failed */
SLOGE("encryption failed - rebooting into recovery to wipe data\n");
mkdir("/cache/recovery", 0700);
- int fd = open("/cache/recovery/command", O_RDWR|O_CREAT|O_TRUNC);
+ int fd = open("/cache/recovery/command", O_RDWR|O_CREAT|O_TRUNC, 0600);
if (fd >= 0) {
write(fd, "--wipe_data", strlen("--wipe_data") + 1);
close(fd);