diff options
author | Ken Sumrall <ksumrall@android.com> | 2012-06-14 20:55:28 -0700 |
---|---|---|
committer | Ken Sumrall <ksumrall@android.com> | 2012-06-15 14:46:53 -0700 |
commit | 425524dba1552ab3d2ad39e205e65d0a2af997f2 (patch) | |
tree | 5fae3becff69d1c5d1cdd64d3ec3f0c14affe1c5 | |
parent | 418367112c96f6ce45aa142d613a575046b7f65f (diff) | |
download | system_vold-425524dba1552ab3d2ad39e205e65d0a2af997f2.zip system_vold-425524dba1552ab3d2ad39e205e65d0a2af997f2.tar.gz system_vold-425524dba1552ab3d2ad39e205e65d0a2af997f2.tar.bz2 |
Unmount all asec apps before encrypting
Now that forward locked apps are stored on /data as asec image files
that are mounted, they need to be unmounted before /data can be unmounted
so it can be encrypted.
Change-Id: I7c87deb52aaed21c8ad8ce8aceb7c15c2338620a
-rw-r--r-- | VolumeManager.cpp | 57 | ||||
-rw-r--r-- | VolumeManager.h | 2 | ||||
-rw-r--r-- | cryptfs.c | 7 |
3 files changed, 66 insertions, 0 deletions
diff --git a/VolumeManager.cpp b/VolumeManager.cpp index f5c254f..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> @@ -1360,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 @@ -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 |