Update sandbox structure for apps with sharedUserIds.

For apps with sharedUserIds, sandbox/shared:<shared-user-id> is
currently used as sandbox root. Given that <shared-user-id> can
be upto 255 characters, adding "shared:" might tip over the
filename limit on ext4 filesystems. So, instead use
sandbox/shared/<shared-user-id> as the sandbox root.

Bug: 111890351
Test: manual
Change-Id: Iba437b3eed59f9eb3094a823e8bf2a5a58410fd7
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 2b8f8d4..2a8e8b7 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -389,6 +389,13 @@
     if (sandboxRoot.empty()) {
         return -errno;
     }
+    std::string sharedSandboxRoot;
+    StringAppendF(&sharedSandboxRoot, "%s/shared", sandboxRoot.c_str());
+    // Create shared sandbox base dir for apps with sharedUserIds
+    if (fs_prepare_dir(sharedSandboxRoot.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) {
+        PLOG(ERROR) << "fs_prepare_dir failed on " << sharedSandboxRoot;
+        return -errno;
+    }
 
     std::string dataRoot = prepareSubDirs(primaryRoot, "Android/data/",
             0700, AID_ROOT, AID_ROOT);
@@ -490,8 +497,12 @@
 
 std::string VolumeManager::prepareSandboxSource(uid_t uid, const std::string& sandboxId,
         const std::string& sandboxRootDir) {
-    std::string sandboxSourceDir = StringPrintf("%s/%s",
-            sandboxRootDir.c_str(), sandboxId.c_str());
+    std::string sandboxSourceDir(sandboxRootDir);
+    if (android::base::StartsWith(sandboxId, "shared:")) {
+        StringAppendF(&sandboxSourceDir, "/shared/%s", sandboxId.substr(7).c_str());
+    } else {
+        StringAppendF(&sandboxSourceDir, "/%s", sandboxId.c_str());
+    }
     if (fs_prepare_dir(sandboxSourceDir.c_str(), 0755, uid, uid) != 0) {
         PLOG(ERROR) << "fs_prepare_dir failed on " << sandboxSourceDir;
         return kEmptyString;