From 2768efdf9fe67d179f6cb733e6541f04b6f2bf46 Mon Sep 17 00:00:00 2001 From: Doug Zongker Date: Mon, 13 Jan 2014 10:11:20 -0800 Subject: remove dead code from minzip minzip had some features that were used when reading APKs, but APK handling now uses libziparchive instead of minzip. Remove these unused functions. Change-Id: Iead89209a716bfe9e3d339bf85b3e97e33a41f35 --- minzip/SysUtil.c | 117 ------------------------------------------------------- 1 file changed, 117 deletions(-) (limited to 'minzip/SysUtil.c') diff --git a/minzip/SysUtil.c b/minzip/SysUtil.c index 31c76d6d4..e6f650644 100644 --- a/minzip/SysUtil.c +++ b/minzip/SysUtil.c @@ -16,34 +16,6 @@ #include "Log.h" #include "SysUtil.h" -/* - * Having trouble finding a portable way to get this. sysconf(_SC_PAGE_SIZE) - * seems appropriate, but we don't have that on the device. Some systems - * have getpagesize(2), though the linux man page has some odd cautions. - */ -#define DEFAULT_PAGE_SIZE 4096 - - -/* - * Create an anonymous shared memory segment large enough to hold "length" - * bytes. The actual segment may be larger because mmap() operates on - * page boundaries (usually 4K). - */ -static void* sysCreateAnonShmem(size_t length) -{ - void* ptr; - - ptr = mmap(NULL, length, PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_ANON, -1, 0); - if (ptr == MAP_FAILED) { - LOGW("mmap(%d, RW, SHARED|ANON) failed: %s\n", (int) length, - strerror(errno)); - return NULL; - } - - return ptr; -} - static int getFileStartAndLength(int fd, off_t *start_, size_t *length_) { off_t start, end; @@ -73,41 +45,6 @@ static int getFileStartAndLength(int fd, off_t *start_, size_t *length_) return 0; } -/* - * Pull the contents of a file into an new shared memory segment. We grab - * everything from fd's current offset on. - * - * We need to know the length ahead of time so we can allocate a segment - * of sufficient size. - */ -int sysLoadFileInShmem(int fd, MemMapping* pMap) -{ - off_t start; - size_t length, actual; - void* memPtr; - - assert(pMap != NULL); - - if (getFileStartAndLength(fd, &start, &length) < 0) - return -1; - - memPtr = sysCreateAnonShmem(length); - if (memPtr == NULL) - return -1; - - pMap->baseAddr = pMap->addr = memPtr; - pMap->baseLength = pMap->length = length; - - actual = TEMP_FAILURE_RETRY(read(fd, memPtr, length)); - if (actual != length) { - LOGE("only read %d of %d bytes\n", (int) actual, (int) length); - sysReleaseShmem(pMap); - return -1; - } - - return 0; -} - /* * Map a file (from fd's current offset) into a shared, read-only memory * segment. The file offset must be a multiple of the page size. @@ -139,59 +76,6 @@ int sysMapFileInShmem(int fd, MemMapping* pMap) return 0; } -/* - * Map part of a file (from fd's current offset) into a shared, read-only - * memory segment. - * - * On success, returns 0 and fills out "pMap". On failure, returns a nonzero - * value and does not disturb "pMap". - */ -int sysMapFileSegmentInShmem(int fd, off_t start, long length, - MemMapping* pMap) -{ - off_t dummy; - size_t fileLength, actualLength; - off_t actualStart; - int adjust; - void* memPtr; - - assert(pMap != NULL); - - if (getFileStartAndLength(fd, &dummy, &fileLength) < 0) - return -1; - - if (start + length > (long)fileLength) { - LOGW("bad segment: st=%d len=%ld flen=%d\n", - (int) start, length, (int) fileLength); - return -1; - } - - /* adjust to be page-aligned */ - adjust = start % DEFAULT_PAGE_SIZE; - actualStart = start - adjust; - actualLength = length + adjust; - - memPtr = mmap(NULL, actualLength, PROT_READ, MAP_FILE | MAP_SHARED, - fd, actualStart); - if (memPtr == MAP_FAILED) { - LOGW("mmap(%d, R, FILE|SHARED, %d, %d) failed: %s\n", - (int) actualLength, fd, (int) actualStart, strerror(errno)); - return -1; - } - - pMap->baseAddr = memPtr; - pMap->baseLength = actualLength; - pMap->addr = (char*)memPtr + adjust; - pMap->length = length; - - LOGVV("mmap seg (st=%d ln=%d): bp=%p bl=%d ad=%p ln=%d\n", - (int) start, (int) length, - pMap->baseAddr, (int) pMap->baseLength, - pMap->addr, (int) pMap->length); - - return 0; -} - /* * Release a memory mapping. */ @@ -209,4 +93,3 @@ void sysReleaseShmem(MemMapping* pMap) pMap->baseLength = 0; } } - -- cgit v1.2.3 From 99916f0496cfe37891d40f21a9a0e387620a8a60 Mon Sep 17 00:00:00 2001 From: Doug Zongker Date: Mon, 13 Jan 2014 14:16:58 -0800 Subject: do verification and extraction on memory, not files Changes minzip and recovery's file signature verification to work on memory regions, rather than files. For packages which are regular files, install.cpp now mmap()s them into memory and then passes the mapped memory to the verifier and to the minzip library. Support for files which are raw block maps (which will be used when we have packages written to encrypted data partitions) is present but largely untested so far. Bug: 12188746 Change-Id: I12cc3e809834745a489dd9d4ceb558cbccdc3f71 --- minzip/SysUtil.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 134 insertions(+), 18 deletions(-) (limited to 'minzip/SysUtil.c') diff --git a/minzip/SysUtil.c b/minzip/SysUtil.c index e6f650644..2cfa39ae3 100644 --- a/minzip/SysUtil.c +++ b/minzip/SysUtil.c @@ -8,11 +8,14 @@ #include #include #include +#include +#include +#include #include #include #include -#define LOG_TAG "minzip" +#define LOG_TAG "sysutil" #include "Log.h" #include "SysUtil.h" @@ -46,13 +49,13 @@ static int getFileStartAndLength(int fd, off_t *start_, size_t *length_) } /* - * Map a file (from fd's current offset) into a shared, read-only memory + * Map a file (from fd's current offset) into a private, read-only memory * segment. The file offset must be a multiple of the page size. * * On success, returns 0 and fills out "pMap". On failure, returns a nonzero * value and does not disturb "pMap". */ -int sysMapFileInShmem(int fd, MemMapping* pMap) +static int sysMapFD(int fd, MemMapping* pMap) { off_t start; size_t length; @@ -63,33 +66,146 @@ int sysMapFileInShmem(int fd, MemMapping* pMap) if (getFileStartAndLength(fd, &start, &length) < 0) return -1; - memPtr = mmap(NULL, length, PROT_READ, MAP_FILE | MAP_SHARED, fd, start); + memPtr = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, start); if (memPtr == MAP_FAILED) { - LOGW("mmap(%d, R, FILE|SHARED, %d, %d) failed: %s\n", (int) length, + LOGW("mmap(%d, R, PRIVATE, %d, %d) failed: %s\n", (int) length, fd, (int) start, strerror(errno)); return -1; } - pMap->baseAddr = pMap->addr = memPtr; - pMap->baseLength = pMap->length = length; + pMap->addr = memPtr; + pMap->length = length; + pMap->range_count = 1; + pMap->ranges = malloc(sizeof(MappedRange)); + pMap->ranges[0].addr = memPtr; + pMap->ranges[0].length = length; return 0; } +static int sysMapBlockFile(FILE* mapf, MemMapping* pMap) +{ + char block_dev[PATH_MAX+1]; + size_t size; + unsigned int blksize; + unsigned int blocks; + unsigned int range_count; + unsigned int i; + + if (fgets(block_dev, sizeof(block_dev), mapf) == NULL) { + LOGW("failed to read block device from header\n"); + return -1; + } + for (i = 0; i < sizeof(block_dev); ++i) { + if (block_dev[i] == '\n') { + block_dev[i] = 0; + break; + } + } + + if (fscanf(mapf, "%d %d\n%d\n", &size, &blksize, &range_count) != 3) { + LOGW("failed to parse block map header\n"); + return -1; + } + + blocks = ((size-1) / blksize) + 1; + + pMap->range_count = range_count; + pMap->ranges = malloc(range_count * sizeof(MappedRange)); + memset(pMap->ranges, 0, range_count * sizeof(MappedRange)); + + // Reserve enough contiguous address space for the whole file. + unsigned char* reserve; + reserve = mmap64(NULL, blocks * blksize, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); + if (reserve == MAP_FAILED) { + LOGW("failed to reserve address space: %s\n", strerror(errno)); + return -1; + } + + pMap->ranges[range_count-1].addr = reserve; + pMap->ranges[range_count-1].length = blocks * blksize; + + int fd = open(block_dev, O_RDONLY); + if (fd < 0) { + LOGW("failed to open block device %s: %s\n", block_dev, strerror(errno)); + return -1; + } + + unsigned char* next = reserve; + for (i = 0; i < range_count; ++i) { + int start, end; + if (fscanf(mapf, "%d %d\n", &start, &end) != 2) { + LOGW("failed to parse range %d in block map\n", i); + return -1; + } + + void* addr = mmap64(next, (end-start)*blksize, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, ((off64_t)start)*blksize); + if (addr == MAP_FAILED) { + LOGW("failed to map block %d: %s\n", i, strerror(errno)); + return -1; + } + pMap->ranges[i].addr = addr; + pMap->ranges[i].length = (end-start)*blksize; + + next += pMap->ranges[i].length; + } + + pMap->addr = reserve; + pMap->length = size; + + return 0; +} + +int sysMapFile(const char* fn, MemMapping* pMap) +{ + memset(pMap, 0, sizeof(*pMap)); + + if (fn && fn[0] == '@') { + // A map of blocks + FILE* mapf = fopen(fn+1, "r"); + if (mapf == NULL) { + LOGV("Unable to open '%s': %s\n", fn+1, strerror(errno)); + return -1; + } + + if (sysMapBlockFile(mapf, pMap) != 0) { + LOGW("Map of '%s' failed\n", fn); + return -1; + } + + fclose(mapf); + } else { + // This is a regular file. + int fd = open(fn, O_RDONLY, 0); + if (fd < 0) { + LOGE("Unable to open '%s': %s\n", fn, strerror(errno)); + return -1; + } + + if (sysMapFD(fd, pMap) != 0) { + LOGE("Map of '%s' failed\n", fn); + close(fd); + return -1; + } + + close(fd); + } + return 0; +} + /* * Release a memory mapping. */ -void sysReleaseShmem(MemMapping* pMap) +void sysReleaseMap(MemMapping* pMap) { - if (pMap->baseAddr == NULL && pMap->baseLength == 0) - return; - - if (munmap(pMap->baseAddr, pMap->baseLength) < 0) { - LOGW("munmap(%p, %d) failed: %s\n", - pMap->baseAddr, (int)pMap->baseLength, strerror(errno)); - } else { - LOGV("munmap(%p, %d) succeeded\n", pMap->baseAddr, pMap->baseLength); - pMap->baseAddr = NULL; - pMap->baseLength = 0; + int i; + for (i = 0; i < pMap->range_count; ++i) { + if (munmap(pMap->ranges[i].addr, pMap->ranges[i].length) < 0) { + LOGW("munmap(%p, %d) failed: %s\n", + pMap->ranges[i].addr, (int)pMap->ranges[i].length, strerror(errno)); + } } + free(pMap->ranges); + pMap->ranges = NULL; + pMap->range_count = 0; } -- cgit v1.2.3 From 19a8e2463c31a97121c35b4666a8e6879fa7e338 Mon Sep 17 00:00:00 2001 From: Doug Zongker Date: Tue, 21 Jan 2014 09:25:41 -0800 Subject: log extra info for debugging Make recovery log its PID, and when we use a block map file, log how many ranges it contains. Change-Id: I1b4299f8163af68a770b48c029ae25e6cb45d26b --- minzip/SysUtil.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'minzip/SysUtil.c') diff --git a/minzip/SysUtil.c b/minzip/SysUtil.c index 2cfa39ae3..c046a8cf2 100644 --- a/minzip/SysUtil.c +++ b/minzip/SysUtil.c @@ -153,6 +153,8 @@ static int sysMapBlockFile(FILE* mapf, MemMapping* pMap) pMap->addr = reserve; pMap->length = size; + LOGI("mmapped %d ranges\n", range_count); + return 0; } -- cgit v1.2.3 From 76b245c24c12feec2381c423de2f7ffe4b78d7f0 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Mon, 17 Mar 2014 15:35:52 -0700 Subject: minzip: 64 bit build issue Regression - verification and extraction on memory, not files Bug: 12188746 Change-Id: Ib6facc4aff6be3a31a7d184ef1c493fdd4012c21 --- minzip/SysUtil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'minzip/SysUtil.c') diff --git a/minzip/SysUtil.c b/minzip/SysUtil.c index c046a8cf2..ac6f5c33f 100644 --- a/minzip/SysUtil.c +++ b/minzip/SysUtil.c @@ -103,7 +103,7 @@ static int sysMapBlockFile(FILE* mapf, MemMapping* pMap) } } - if (fscanf(mapf, "%d %d\n%d\n", &size, &blksize, &range_count) != 3) { + if (fscanf(mapf, "%zu %u\n%u\n", &size, &blksize, &range_count) != 3) { LOGW("failed to parse block map header\n"); return -1; } -- cgit v1.2.3