Commits

Anonymous committed 4d5d99c Merge

am 7cf05b15: am 2f0a1d66: am 7f6932df: am 35ab6119: am 3e03bf8a: am fd2dcf90: am f4770dcf: am 0de7c611: Validate asec names.

* commit '7cf05b15b76b91aa07182e86a730d7552b23130c':
Validate asec names.

  • Participants
  • Parent commits 7bdfa52, 7cf05b1
  • Tags android-4.4.3_r1, android-4.4.3_r1.0.1 7
    1. android-4.4.3_r1.1
    2. android-4.4.3_r1.1.0.1
    3. android-4.4.4_r1
    4. android-4.4.4_r1.0.1
    5. android-4.4.4_r2
    6. android-4.4.4_r2.0.1
    7. android-4.4w_r1

Comments (0)

Files changed (2)

File VolumeManager.cpp

 int VolumeManager::getAsecMountPath(const char *id, char *buffer, int maxlen) {
     char asecFileName[255];
 
+    if (!isLegalAsecId(id)) {
+        SLOGE("getAsecMountPath: Invalid asec id \"%s\"", id);
+        errno = EINVAL;
+        return -1;
+    }
+
     if (findAsec(id, asecFileName, sizeof(asecFileName))) {
         SLOGE("Couldn't find ASEC %s", id);
         return -1;
 int VolumeManager::getAsecFilesystemPath(const char *id, char *buffer, int maxlen) {
     char asecFileName[255];
 
+    if (!isLegalAsecId(id)) {
+        SLOGE("getAsecFilesystemPath: Invalid asec id \"%s\"", id);
+        errno = EINVAL;
+        return -1;
+    }
+
     if (findAsec(id, asecFileName, sizeof(asecFileName))) {
         SLOGE("Couldn't find ASEC %s", id);
         return -1;
     struct asec_superblock sb;
     memset(&sb, 0, sizeof(sb));
 
+    if (!isLegalAsecId(id)) {
+        SLOGE("createAsec: Invalid asec id \"%s\"", id);
+        errno = EINVAL;
+        return -1;
+    }
+
     const bool wantFilesystem = strcmp(fstype, "none");
     bool usingExt4 = false;
     if (wantFilesystem) {
     char loopDevice[255];
     char mountPoint[255];
 
+    if (!isLegalAsecId(id)) {
+        SLOGE("finalizeAsec: Invalid asec id \"%s\"", id);
+        errno = EINVAL;
+        return -1;
+    }
+
     if (findAsec(id, asecFileName, sizeof(asecFileName))) {
         SLOGE("Couldn't find ASEC %s", id);
         return -1;
         return -1;
     }
 
+    if (!isLegalAsecId(id)) {
+        SLOGE("fixupAsecPermissions: Invalid asec id \"%s\"", id);
+        errno = EINVAL;
+        return -1;
+    }
+
     if (findAsec(id, asecFileName, sizeof(asecFileName))) {
         SLOGE("Couldn't find ASEC %s", id);
         return -1;
 
     const char *dir;
 
+    if (!isLegalAsecId(id1)) {
+        SLOGE("renameAsec: Invalid asec id1 \"%s\"", id1);
+        errno = EINVAL;
+        return -1;
+    }
+
+    if (!isLegalAsecId(id2)) {
+        SLOGE("renameAsec: Invalid asec id2 \"%s\"", id2);
+        errno = EINVAL;
+        return -1;
+    }
+
     if (findAsec(id1, asecFilename1, sizeof(asecFilename1), &dir)) {
         SLOGE("Couldn't find ASEC %s", id1);
         return -1;
     char asecFileName[255];
     char mountPoint[255];
 
+    if (!isLegalAsecId(id)) {
+        SLOGE("unmountAsec: Invalid asec id \"%s\"", id);
+        errno = EINVAL;
+        return -1;
+    }
+
     if (findAsec(id, asecFileName, sizeof(asecFileName))) {
         SLOGE("Couldn't find ASEC %s", id);
         return -1;
     char asecFileName[255];
     char mountPoint[255];
 
+    if (!isLegalAsecId(id)) {
+        SLOGE("destroyAsec: Invalid asec id \"%s\"", id);
+        errno = EINVAL;
+        return -1;
+    }
+
     if (findAsec(id, asecFileName, sizeof(asecFileName))) {
         SLOGE("Couldn't find ASEC %s", id);
         return -1;
     return 0;
 }
 
+/*
+ * Legal ASEC ids consist of alphanumeric characters, '-',
+ * '_', or '.'. ".." is not allowed. The first or last character
+ * of the ASEC id cannot be '.' (dot).
+ */
+bool VolumeManager::isLegalAsecId(const char *id) const {
+    size_t i;
+    size_t len = strlen(id);
+
+    if (len == 0) {
+        return false;
+    }
+    if ((id[0] == '.') || (id[len - 1] == '.')) {
+        return false;
+    }
+
+    for (i = 0; i < len; i++) {
+        if (id[i] == '.') {
+            // i=0 is guaranteed never to have a dot. See above.
+            if (id[i-1] == '.') return false;
+            continue;
+        }
+        if (id[i] == '_' || id[i] == '-') continue;
+        if (id[i] >= 'a' && id[i] <= 'z') continue;
+        if (id[i] >= 'A' && id[i] <= 'Z') continue;
+        if (id[i] >= '0' && id[i] <= '9') continue;
+        return false;
+    }
+
+    return true;
+}
+
 bool VolumeManager::isAsecInDirectory(const char *dir, const char *asecName) const {
     int dirfd = open(dir, O_DIRECTORY);
     if (dirfd < 0) {
     const int idLen = strlen(id);
     char *asecName;
 
+    if (!isLegalAsecId(id)) {
+        SLOGE("findAsec: Invalid asec id \"%s\"", id);
+        errno = EINVAL;
+        return -1;
+    }
+
     if (asprintf(&asecName, "%s.asec", id) < 0) {
         SLOGE("Couldn't allocate string to write ASEC name");
         return -1;
     char asecFileName[255];
     char mountPoint[255];
 
+    if (!isLegalAsecId(id)) {
+        SLOGE("mountAsec: Invalid asec id \"%s\"", id);
+        errno = EINVAL;
+        return -1;
+    }
+
     if (findAsec(id, asecFileName, sizeof(asecFileName))) {
         SLOGE("Couldn't find ASEC %s", id);
         return -1;

File VolumeManager.h

     void readInitialState();
     bool isMountpointMounted(const char *mp);
     bool isAsecInDirectory(const char *dir, const char *asec) const;
+    bool isLegalAsecId(const char *id) const;
 };
 
 extern "C" {