Loading run-as/package.c +59 −32 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <fcntl.h> #include <fcntl.h> #include <unistd.h> #include <unistd.h> #include <sys/stat.h> #include <sys/stat.h> #include <sys/mman.h> #include <private/android_filesystem_config.h> #include <private/android_filesystem_config.h> #include "package.h" #include "package.h" Loading @@ -43,9 +44,6 @@ /* The file containing the list of installed packages on the system */ /* The file containing the list of installed packages on the system */ #define PACKAGES_LIST_FILE "/data/system/packages.list" #define PACKAGES_LIST_FILE "/data/system/packages.list" /* This should be large enough to hold the content of the package database file */ #define PACKAGES_LIST_BUFFER_SIZE 65536 /* Copy 'srclen' string bytes from 'src' into buffer 'dst' of size 'dstlen' /* Copy 'srclen' string bytes from 'src' into buffer 'dst' of size 'dstlen' * This function always zero-terminate the destination buffer unless * This function always zero-terminate the destination buffer unless * 'dstlen' is 0, even in case of overflow. * 'dstlen' is 0, even in case of overflow. Loading @@ -67,40 +65,63 @@ string_copy(char* dst, size_t dstlen, const char* src, size_t srclen) *dst = '\0'; /* zero-terminate result */ *dst = '\0'; /* zero-terminate result */ } } /* Read up to 'buffsize' bytes into 'buff' from the file /* Open 'filename' and map it into our address-space. * named 'filename'. Return byte length on success, or -1 * Returns buffer address, or NULL on error * on error. * On exit, *filesize will be set to the file's size, or 0 on error */ */ static int static void* read_file(const char* filename, char* buff, size_t buffsize) map_file(const char* filename, size_t* filesize) { { int fd, len, old_errno; int fd, ret, old_errno; struct stat st; size_t length = 0; void* address = NULL; /* check the input buffer size */ *filesize = 0; if (buffsize >= INT_MAX) { errno = EINVAL; return -1; } /* open the file for reading */ /* open the file for reading */ do { fd = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); fd = open(filename, O_RDONLY); } while (fd < 0 && errno == EINTR); if (fd < 0) if (fd < 0) return -1; return NULL; /* read the content */ /* get its size */ do { ret = TEMP_FAILURE_RETRY(fstat(fd, &st)); len = read(fd, buff, buffsize); if (ret < 0) } while (len < 0 && errno == EINTR); goto EXIT; /* Ensure that the size is not ridiculously large */ length = (size_t)st.st_size; if ((off_t)length != st.st_size) { errno = ENOMEM; goto EXIT; } /* Memory-map the file now */ address = TEMP_FAILURE_RETRY(mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0)); if (address == MAP_FAILED) { address = NULL; goto EXIT; } /* We're good, return size */ *filesize = length; EXIT: /* close the file, preserve old errno for better diagnostics */ /* close the file, preserve old errno for better diagnostics */ old_errno = errno; old_errno = errno; close(fd); close(fd); errno = old_errno; errno = old_errno; return len; return address; } /* unmap the file, but preserve errno */ static void unmap_file(void* address, size_t size) { int old_errno = errno; TEMP_FAILURE_RETRY(munmap(address, size)); errno = old_errno; } } /* Check that a given directory: /* Check that a given directory: Loading Loading @@ -371,18 +392,18 @@ BAD: int int get_package_info(const char* pkgName, PackageInfo *info) get_package_info(const char* pkgName, PackageInfo *info) { { static char buffer[PACKAGES_LIST_BUFFER_SIZE]; char* buffer; int buffer_len; size_t buffer_len; const char* p; const char* p; const char* buffer_end; const char* buffer_end; int result; int result = -1; info->uid = 0; info->uid = 0; info->isDebuggable = 0; info->isDebuggable = 0; info->dataDir[0] = '\0'; info->dataDir[0] = '\0'; buffer_len = read_file(PACKAGES_LIST_FILE, buffer, sizeof buffer); buffer = map_file(PACKAGES_LIST_FILE, &buffer_len); if (buffer_len < 0) if (buffer == NULL) return -1; return -1; p = buffer; p = buffer; Loading Loading @@ -455,7 +476,8 @@ get_package_info(const char* pkgName, PackageInfo *info) string_copy(info->dataDir, sizeof info->dataDir, p, q - p); string_copy(info->dataDir, sizeof info->dataDir, p, q - p); /* Ignore the rest */ /* Ignore the rest */ return 0; result = 0; goto EXIT; NEXT_LINE: NEXT_LINE: p = next; p = next; Loading @@ -463,9 +485,14 @@ get_package_info(const char* pkgName, PackageInfo *info) /* the package is unknown */ /* the package is unknown */ errno = ENOENT; errno = ENOENT; return -1; result = -1; goto EXIT; BAD_FORMAT: BAD_FORMAT: errno = EINVAL; errno = EINVAL; return -1; result = -1; EXIT: unmap_file(buffer, buffer_len); return result; } } Loading
run-as/package.c +59 −32 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <fcntl.h> #include <fcntl.h> #include <unistd.h> #include <unistd.h> #include <sys/stat.h> #include <sys/stat.h> #include <sys/mman.h> #include <private/android_filesystem_config.h> #include <private/android_filesystem_config.h> #include "package.h" #include "package.h" Loading @@ -43,9 +44,6 @@ /* The file containing the list of installed packages on the system */ /* The file containing the list of installed packages on the system */ #define PACKAGES_LIST_FILE "/data/system/packages.list" #define PACKAGES_LIST_FILE "/data/system/packages.list" /* This should be large enough to hold the content of the package database file */ #define PACKAGES_LIST_BUFFER_SIZE 65536 /* Copy 'srclen' string bytes from 'src' into buffer 'dst' of size 'dstlen' /* Copy 'srclen' string bytes from 'src' into buffer 'dst' of size 'dstlen' * This function always zero-terminate the destination buffer unless * This function always zero-terminate the destination buffer unless * 'dstlen' is 0, even in case of overflow. * 'dstlen' is 0, even in case of overflow. Loading @@ -67,40 +65,63 @@ string_copy(char* dst, size_t dstlen, const char* src, size_t srclen) *dst = '\0'; /* zero-terminate result */ *dst = '\0'; /* zero-terminate result */ } } /* Read up to 'buffsize' bytes into 'buff' from the file /* Open 'filename' and map it into our address-space. * named 'filename'. Return byte length on success, or -1 * Returns buffer address, or NULL on error * on error. * On exit, *filesize will be set to the file's size, or 0 on error */ */ static int static void* read_file(const char* filename, char* buff, size_t buffsize) map_file(const char* filename, size_t* filesize) { { int fd, len, old_errno; int fd, ret, old_errno; struct stat st; size_t length = 0; void* address = NULL; /* check the input buffer size */ *filesize = 0; if (buffsize >= INT_MAX) { errno = EINVAL; return -1; } /* open the file for reading */ /* open the file for reading */ do { fd = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); fd = open(filename, O_RDONLY); } while (fd < 0 && errno == EINTR); if (fd < 0) if (fd < 0) return -1; return NULL; /* read the content */ /* get its size */ do { ret = TEMP_FAILURE_RETRY(fstat(fd, &st)); len = read(fd, buff, buffsize); if (ret < 0) } while (len < 0 && errno == EINTR); goto EXIT; /* Ensure that the size is not ridiculously large */ length = (size_t)st.st_size; if ((off_t)length != st.st_size) { errno = ENOMEM; goto EXIT; } /* Memory-map the file now */ address = TEMP_FAILURE_RETRY(mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0)); if (address == MAP_FAILED) { address = NULL; goto EXIT; } /* We're good, return size */ *filesize = length; EXIT: /* close the file, preserve old errno for better diagnostics */ /* close the file, preserve old errno for better diagnostics */ old_errno = errno; old_errno = errno; close(fd); close(fd); errno = old_errno; errno = old_errno; return len; return address; } /* unmap the file, but preserve errno */ static void unmap_file(void* address, size_t size) { int old_errno = errno; TEMP_FAILURE_RETRY(munmap(address, size)); errno = old_errno; } } /* Check that a given directory: /* Check that a given directory: Loading Loading @@ -371,18 +392,18 @@ BAD: int int get_package_info(const char* pkgName, PackageInfo *info) get_package_info(const char* pkgName, PackageInfo *info) { { static char buffer[PACKAGES_LIST_BUFFER_SIZE]; char* buffer; int buffer_len; size_t buffer_len; const char* p; const char* p; const char* buffer_end; const char* buffer_end; int result; int result = -1; info->uid = 0; info->uid = 0; info->isDebuggable = 0; info->isDebuggable = 0; info->dataDir[0] = '\0'; info->dataDir[0] = '\0'; buffer_len = read_file(PACKAGES_LIST_FILE, buffer, sizeof buffer); buffer = map_file(PACKAGES_LIST_FILE, &buffer_len); if (buffer_len < 0) if (buffer == NULL) return -1; return -1; p = buffer; p = buffer; Loading Loading @@ -455,7 +476,8 @@ get_package_info(const char* pkgName, PackageInfo *info) string_copy(info->dataDir, sizeof info->dataDir, p, q - p); string_copy(info->dataDir, sizeof info->dataDir, p, q - p); /* Ignore the rest */ /* Ignore the rest */ return 0; result = 0; goto EXIT; NEXT_LINE: NEXT_LINE: p = next; p = next; Loading @@ -463,9 +485,14 @@ get_package_info(const char* pkgName, PackageInfo *info) /* the package is unknown */ /* the package is unknown */ errno = ENOENT; errno = ENOENT; return -1; result = -1; goto EXIT; BAD_FORMAT: BAD_FORMAT: errno = EINVAL; errno = EINVAL; return -1; result = -1; EXIT: unmap_file(buffer, buffer_len); return result; } }