summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Kralevich <nnk@google.com>2014-01-27 19:32:29 -0800
committerAndroid Git Automerger <android-git-automerger@android.com>2014-01-27 19:32:29 -0800
commit7cf05b15b76b91aa07182e86a730d7552b23130c (patch)
tree56e110df1adbb885d31b9441d62025904ef6f857
parent5d09126ad1cd10c74e676fb158f1d057a37180b2 (diff)
parent2f0a1d66585fb44f59d913d3417422486ef10225 (diff)
downloadvold-7cf05b15b76b91aa07182e86a730d7552b23130c.tar.gz
am 2f0a1d66: am 7f6932df: am 35ab6119: am 3e03bf8a: am fd2dcf90: am f4770dcf: am 0de7c611: Validate asec names.
* commit '2f0a1d66585fb44f59d913d3417422486ef10225': Validate asec names.
-rw-r--r--VolumeManager.cpp98
-rw-r--r--VolumeManager.h1
2 files changed, 99 insertions, 0 deletions
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index a1930d18..70f2b13f 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 198b5a97..77fff871 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" {