diff options
author | Nick Kralevich <nnk@google.com> | 2014-01-27 19:27:11 -0800 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-01-27 19:27:11 -0800 |
commit | 2f0a1d66585fb44f59d913d3417422486ef10225 (patch) | |
tree | 8ab84bffc0a181d51363662a6abcdc389495c1d8 | |
parent | c587269c5a34d4e7412ff42e53ed6312359a8505 (diff) | |
parent | 7f6932df89756f796c3a1f04f748db39a0564561 (diff) | |
download | android_system_vold-2f0a1d66585fb44f59d913d3417422486ef10225.tar.gz android_system_vold-2f0a1d66585fb44f59d913d3417422486ef10225.tar.bz2 android_system_vold-2f0a1d66585fb44f59d913d3417422486ef10225.zip |
am 7f6932df: am 35ab6119: am 3e03bf8a: am fd2dcf90: am f4770dcf: am 0de7c611: Validate asec names.
* commit '7f6932df89756f796c3a1f04f748db39a0564561':
Validate asec names.
-rw-r--r-- | VolumeManager.cpp | 98 | ||||
-rw-r--r-- | VolumeManager.h | 1 |
2 files changed, 99 insertions, 0 deletions
diff --git a/VolumeManager.cpp b/VolumeManager.cpp index a1930d1..70f2b13 100644 --- a/VolumeManager.cpp +++ b/VolumeManager.cpp @@ -208,6 +208,12 @@ int VolumeManager::getObbMountPath(const char *sourceFile, char *mountPath, int 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; @@ -232,6 +238,12 @@ int VolumeManager::getAsecMountPath(const char *id, char *buffer, int maxlen) { 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; @@ -257,6 +269,12 @@ int VolumeManager::createAsec(const char *id, unsigned int numSectors, const cha 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) { @@ -480,6 +498,12 @@ int VolumeManager::finalizeAsec(const char *id) { 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; @@ -537,6 +561,12 @@ int VolumeManager::fixupAsecPermissions(const char *id, gid_t gid, const char* f 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; @@ -650,6 +680,18 @@ int VolumeManager::renameAsec(const char *id1, const char *id2) { 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; @@ -706,6 +748,12 @@ int VolumeManager::unmountAsec(const char *id, bool force) { 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; @@ -830,6 +878,12 @@ int VolumeManager::destroyAsec(const char *id, bool force) { 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; @@ -862,6 +916,38 @@ int VolumeManager::destroyAsec(const char *id, bool force) { 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) { @@ -886,6 +972,12 @@ int VolumeManager::findAsec(const char *id, char *asecPath, size_t asecPathLen, 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; @@ -922,6 +1014,12 @@ int VolumeManager::mountAsec(const char *id, const char *key, int ownerUid) { 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; diff --git a/VolumeManager.h b/VolumeManager.h index 198b5a9..77fff87 100644 --- a/VolumeManager.h +++ b/VolumeManager.h @@ -145,6 +145,7 @@ private: void readInitialState(); bool isMountpointMounted(const char *mp); bool isAsecInDirectory(const char *dir, const char *asec) const; + bool isLegalAsecId(const char *id) const; }; extern "C" { |