vold: Stage the mounting of media to hide the ASEC imagefile directory

  In order to protect the '/android_secure' directory on VFAT removable media
from being mucked with by 3rd party applications on the device, we hide the
directory with a read-only, zero-sized tmpfs mounted on-top. A reference to the
hidden directory is kept by a bind-mount which is mounted at a location which
only root can access.

Staging consists of:
  1. Mount checked media at a secure location (/mnt/secure/staging)
  2. Ensure /android_secure exists on the media, (creating if it doesnt)
  3. Bind-mount /mnt/secure/staging/android_secure -> /mnt/secure/asec
     (where only root can access it)
  4. Mount an RDONLY zero-sized tmpfs over /mnt/secure/staging/android_secure
  5. Atomically move /mnt/secure/staging to the publicly accessable storage
     directory (/mnt/sdcard)

Signed-off-by: San Mehat <san@google.com>
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 72ec3da..5a77c13 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -161,10 +161,8 @@
 }
 
 int VolumeManager::getAsecMountPath(const char *id, char *buffer, int maxlen) {
-    char mountPoint[255];
 
-    snprintf(mountPoint, sizeof(mountPoint), "/asec/%s", id);
-    snprintf(buffer, maxlen, "/asec/%s", id);
+    snprintf(buffer, maxlen, "%s/%s", Volume::ASECDIR, id);
     return 0;
 }
 
@@ -177,17 +175,14 @@
         return -1;
     }
 
-    mkdir("/sdcard/android_secure", 0777);
-
     if (lookupVolume(id)) {
-        LOGE("ASEC volume '%s' currently exists", id);
+        LOGE("ASEC id '%s' currently exists", id);
         errno = EADDRINUSE;
         return -1;
     }
 
     char asecFileName[255];
-    snprintf(asecFileName, sizeof(asecFileName),
-             "/sdcard/android_secure/%s.asec", id);
+    snprintf(asecFileName, sizeof(asecFileName), "%s/%s.asec", Volume::SEC_ASECDIR, id);
 
     if (!access(asecFileName, F_OK)) {
         LOGE("ASEC file '%s' currently exists - destroy it first! (%s)",
@@ -236,7 +231,7 @@
 
     char mountPoint[255];
 
-    snprintf(mountPoint, sizeof(mountPoint), "/asec/%s", id);
+    snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id);
     if (mkdir(mountPoint, 0777)) {
         if (errno != EEXIST) {
             LOGE("Mountpoint creation failed (%s)", strerror(errno));
@@ -270,15 +265,14 @@
     char loopDevice[255];
     char mountPoint[255];
 
-    snprintf(asecFileName, sizeof(asecFileName),
-             "/sdcard/android_secure/%s.asec", id);
+    snprintf(asecFileName, sizeof(asecFileName), "%s/%s.asec", Volume::SEC_ASECDIR, id);
 
     if (Loop::lookupActive(asecFileName, loopDevice, sizeof(loopDevice))) {
         LOGE("Unable to finalize %s (%s)", id, strerror(errno));
         return -1;
     }
 
-    snprintf(mountPoint, sizeof(mountPoint), "/asec/%s", id);
+    snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id);
     // XXX:
     if (Fat::doMount(loopDevice, mountPoint, true, true, 0, 0, 0227, false)) {
         LOGE("ASEC finalize mount failed (%s)", strerror(errno));
@@ -294,10 +288,10 @@
     char *asecFilename2;
     char mountPoint[255];
 
-    asprintf(&asecFilename1, "/sdcard/android_secure/%s.asec", id1);
-    asprintf(&asecFilename2, "/sdcard/android_secure/%s.asec", id2);
+    asprintf(&asecFilename1, "%s/%s.asec", Volume::SEC_ASECDIR, id1);
+    asprintf(&asecFilename2, "%s/%s.asec", Volume::SEC_ASECDIR, id2);
 
-    snprintf(mountPoint, sizeof(mountPoint), "/asec/%s", id1);
+    snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id1);
     if (isMountpointMounted(mountPoint)) {
         LOGW("Rename attempt when src mounted");
         errno = EBUSY;
@@ -330,9 +324,8 @@
     char asecFileName[255];
     char mountPoint[255];
 
-    snprintf(asecFileName, sizeof(asecFileName),
-             "/sdcard/android_secure/%s.asec", id);
-    snprintf(mountPoint, sizeof(mountPoint), "/asec/%s", id);
+    snprintf(asecFileName, sizeof(asecFileName), "%s/%s.asec", Volume::SEC_ASECDIR, id);
+    snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id);
 
     if (!isMountpointMounted(mountPoint)) {
         LOGE("Unmount request for ASEC %s when not mounted", id);
@@ -403,9 +396,7 @@
     char asecFileName[255];
     char mountPoint[255];
 
-    snprintf(asecFileName, sizeof(asecFileName),
-             "/sdcard/android_secure/%s.asec", id);
-    snprintf(mountPoint, sizeof(mountPoint), "/asec/%s", id);
+    snprintf(asecFileName, sizeof(asecFileName), "%s/%s.asec", Volume::SEC_ASECDIR, id);
 
     if (isMountpointMounted(mountPoint)) {
         LOGD("Unmounting container before destroy");
@@ -428,9 +419,8 @@
     char asecFileName[255];
     char mountPoint[255];
 
-    snprintf(asecFileName, sizeof(asecFileName),
-             "/sdcard/android_secure/%s.asec", id);
-    snprintf(mountPoint, sizeof(mountPoint), "/asec/%s", id);
+    snprintf(asecFileName, sizeof(asecFileName), "%s/%s.asec", Volume::SEC_ASECDIR, id);
+    snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id);
 
     if (isMountpointMounted(mountPoint)) {
         LOGE("ASEC %s already mounted", id);