Validate asec names.

Make sure asec names only contain alphanumeric, underscores,
dots, or dashes. Don't allow double dots.

Bug: 12504045
Change-Id: I3dd0350c79327dc91a5a10d5724d85d99814e769
This commit is contained in:
Nick Kralevich 2014-01-27 14:58:06 -08:00
parent 01012342f4
commit 6696260965
2 changed files with 99 additions and 0 deletions

View file

@ -209,6 +209,12 @@ int VolumeManager::getObbMountPath(const char *sourceFile, char *mountPath, int
int VolumeManager::getAsecMountPath(const char *id, char *buffer, int maxlen) { int VolumeManager::getAsecMountPath(const char *id, char *buffer, int maxlen) {
char asecFileName[255]; char asecFileName[255];
if (!isLegalAsecId(id)) {
SLOGE("getAsecMountPath: Invalid asec id \"%s\"", id);
errno = EINVAL;
return -1;
}
if (findAsec(id, asecFileName, sizeof(asecFileName))) { if (findAsec(id, asecFileName, sizeof(asecFileName))) {
SLOGE("Couldn't find ASEC %s", id); SLOGE("Couldn't find ASEC %s", id);
return -1; return -1;
@ -233,6 +239,12 @@ int VolumeManager::getAsecMountPath(const char *id, char *buffer, int maxlen) {
int VolumeManager::getAsecFilesystemPath(const char *id, char *buffer, int maxlen) { int VolumeManager::getAsecFilesystemPath(const char *id, char *buffer, int maxlen) {
char asecFileName[255]; char asecFileName[255];
if (!isLegalAsecId(id)) {
SLOGE("getAsecFilesystemPath: Invalid asec id \"%s\"", id);
errno = EINVAL;
return -1;
}
if (findAsec(id, asecFileName, sizeof(asecFileName))) { if (findAsec(id, asecFileName, sizeof(asecFileName))) {
SLOGE("Couldn't find ASEC %s", id); SLOGE("Couldn't find ASEC %s", id);
return -1; return -1;
@ -258,6 +270,12 @@ int VolumeManager::createAsec(const char *id, unsigned int numSectors, const cha
struct asec_superblock sb; struct asec_superblock sb;
memset(&sb, 0, sizeof(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"); const bool wantFilesystem = strcmp(fstype, "none");
bool usingExt4 = false; bool usingExt4 = false;
if (wantFilesystem) { if (wantFilesystem) {
@ -481,6 +499,12 @@ int VolumeManager::finalizeAsec(const char *id) {
char loopDevice[255]; char loopDevice[255];
char mountPoint[255]; char mountPoint[255];
if (!isLegalAsecId(id)) {
SLOGE("finalizeAsec: Invalid asec id \"%s\"", id);
errno = EINVAL;
return -1;
}
if (findAsec(id, asecFileName, sizeof(asecFileName))) { if (findAsec(id, asecFileName, sizeof(asecFileName))) {
SLOGE("Couldn't find ASEC %s", id); SLOGE("Couldn't find ASEC %s", id);
return -1; return -1;
@ -538,6 +562,12 @@ int VolumeManager::fixupAsecPermissions(const char *id, gid_t gid, const char* f
return -1; return -1;
} }
if (!isLegalAsecId(id)) {
SLOGE("fixupAsecPermissions: Invalid asec id \"%s\"", id);
errno = EINVAL;
return -1;
}
if (findAsec(id, asecFileName, sizeof(asecFileName))) { if (findAsec(id, asecFileName, sizeof(asecFileName))) {
SLOGE("Couldn't find ASEC %s", id); SLOGE("Couldn't find ASEC %s", id);
return -1; return -1;
@ -651,6 +681,18 @@ int VolumeManager::renameAsec(const char *id1, const char *id2) {
const char *dir; 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)) { if (findAsec(id1, asecFilename1, sizeof(asecFilename1), &dir)) {
SLOGE("Couldn't find ASEC %s", id1); SLOGE("Couldn't find ASEC %s", id1);
return -1; return -1;
@ -707,6 +749,12 @@ int VolumeManager::unmountAsec(const char *id, bool force) {
char asecFileName[255]; char asecFileName[255];
char mountPoint[255]; char mountPoint[255];
if (!isLegalAsecId(id)) {
SLOGE("unmountAsec: Invalid asec id \"%s\"", id);
errno = EINVAL;
return -1;
}
if (findAsec(id, asecFileName, sizeof(asecFileName))) { if (findAsec(id, asecFileName, sizeof(asecFileName))) {
SLOGE("Couldn't find ASEC %s", id); SLOGE("Couldn't find ASEC %s", id);
return -1; return -1;
@ -831,6 +879,12 @@ int VolumeManager::destroyAsec(const char *id, bool force) {
char asecFileName[255]; char asecFileName[255];
char mountPoint[255]; char mountPoint[255];
if (!isLegalAsecId(id)) {
SLOGE("destroyAsec: Invalid asec id \"%s\"", id);
errno = EINVAL;
return -1;
}
if (findAsec(id, asecFileName, sizeof(asecFileName))) { if (findAsec(id, asecFileName, sizeof(asecFileName))) {
SLOGE("Couldn't find ASEC %s", id); SLOGE("Couldn't find ASEC %s", id);
return -1; return -1;
@ -863,6 +917,38 @@ int VolumeManager::destroyAsec(const char *id, bool force) {
return 0; 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 { bool VolumeManager::isAsecInDirectory(const char *dir, const char *asecName) const {
int dirfd = open(dir, O_DIRECTORY); int dirfd = open(dir, O_DIRECTORY);
if (dirfd < 0) { if (dirfd < 0) {
@ -887,6 +973,12 @@ int VolumeManager::findAsec(const char *id, char *asecPath, size_t asecPathLen,
const int idLen = strlen(id); const int idLen = strlen(id);
char *asecName; char *asecName;
if (!isLegalAsecId(id)) {
SLOGE("findAsec: Invalid asec id \"%s\"", id);
errno = EINVAL;
return -1;
}
if (asprintf(&asecName, "%s.asec", id) < 0) { if (asprintf(&asecName, "%s.asec", id) < 0) {
SLOGE("Couldn't allocate string to write ASEC name"); SLOGE("Couldn't allocate string to write ASEC name");
return -1; return -1;
@ -923,6 +1015,12 @@ int VolumeManager::mountAsec(const char *id, const char *key, int ownerUid) {
char asecFileName[255]; char asecFileName[255];
char mountPoint[255]; char mountPoint[255];
if (!isLegalAsecId(id)) {
SLOGE("mountAsec: Invalid asec id \"%s\"", id);
errno = EINVAL;
return -1;
}
if (findAsec(id, asecFileName, sizeof(asecFileName))) { if (findAsec(id, asecFileName, sizeof(asecFileName))) {
SLOGE("Couldn't find ASEC %s", id); SLOGE("Couldn't find ASEC %s", id);
return -1; return -1;

View file

@ -154,6 +154,7 @@ private:
void readInitialState(); void readInitialState();
bool isMountpointMounted(const char *mp); bool isMountpointMounted(const char *mp);
bool isAsecInDirectory(const char *dir, const char *asec) const; bool isAsecInDirectory(const char *dir, const char *asec) const;
bool isLegalAsecId(const char *id) const;
}; };
extern "C" { extern "C" {