From 64be82755cc42b05775265b87a0c64242a72d0dd Mon Sep 17 00:00:00 2001 From: Doug Zongker Date: Thu, 14 Aug 2014 07:59:28 -0700 Subject: change uncrypt to static linking Bug: 17015157 Change-Id: I3c4bdcf4f11d44b617bb731a48413e3707044d1c --- uncrypt/Android.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/uncrypt/Android.mk b/uncrypt/Android.mk index 756bc964c..ef3cead34 100644 --- a/uncrypt/Android.mk +++ b/uncrypt/Android.mk @@ -25,4 +25,6 @@ LOCAL_STATIC_LIBRARIES := \ libcutils \ libc +LOCAL_FORCE_STATIC_EXECUTABLE := true + include $(BUILD_EXECUTABLE) -- cgit v1.2.3 From f2127b6435eedd2c2c57a480a0ed049fee014406 Mon Sep 17 00:00:00 2001 From: Doug Zongker Date: Thu, 21 Aug 2014 10:47:24 -0700 Subject: fix two bugs in block image updater The computation of file offsets was overflowing for partitions larger than 2 GB. The parsing of the transfer file could fail at the end if the data happened to not be properly null-terminated. Bug: 16984795 Change-Id: I3ce6eb3e54ab7b55aa9bbed252da5a7eacd3317a --- updater/blockimg.c | 50 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/updater/blockimg.c b/updater/blockimg.c index c442ab22a..6d412d5d5 100644 --- a/updater/blockimg.c +++ b/updater/blockimg.c @@ -61,7 +61,7 @@ static RangeSet* parse_range(char* text) { RangeSet* out = malloc(sizeof(RangeSet) + num * sizeof(int)); if (out == NULL) { - fprintf(stderr, "failed to allocate range of %d bytes\n", + fprintf(stderr, "failed to allocate range of %lu bytes\n", sizeof(RangeSet) + num * sizeof(int)); exit(1); } @@ -108,7 +108,7 @@ static void writeblock(int fd, const uint8_t* data, size_t size) { static void check_lseek(int fd, off_t offset, int whence) { while (true) { - int ret = lseek(fd, offset, whence); + off_t ret = lseek(fd, offset, whence); if (ret < 0) { if (errno != EINTR) { fprintf(stderr, "lseek failed: %s\n", strerror(errno)); @@ -128,7 +128,7 @@ static void allocate(size_t size, uint8_t** buffer, size_t* buffer_alloc) { *buffer = (uint8_t*) malloc(size); if (*buffer == NULL) { - fprintf(stderr, "failed to allocate %d bytes\n", size); + fprintf(stderr, "failed to allocate %zu bytes\n", size); exit(1); } *buffer_alloc = size; @@ -165,7 +165,7 @@ static ssize_t RangeSinkWrite(const uint8_t* data, ssize_t size, void* token) { ++rss->p_block; if (rss->p_block < rss->tgt->count) { rss->p_remain = (rss->tgt->pos[rss->p_block*2+1] - rss->tgt->pos[rss->p_block*2]) * BLOCKSIZE; - check_lseek(rss->fd, rss->tgt->pos[rss->p_block*2] * BLOCKSIZE, SEEK_SET); + check_lseek(rss->fd, rss->tgt->pos[rss->p_block*2] * (off_t)BLOCKSIZE, SEEK_SET); } else { // we can't write any more; return how many bytes have // been written so far. @@ -253,12 +253,13 @@ static void* unzip_new_data(void* cookie) { Value* BlockImageUpdateFn(const char* name, State* state, int argc, Expr* argv[]) { Value* blockdev_filename; - Value* transfer_list; + Value* transfer_list_value; + char* transfer_list = NULL; Value* new_data_fn; Value* patch_data_fn; bool success = false; - if (ReadValueArgs(state, argv, 4, &blockdev_filename, &transfer_list, + if (ReadValueArgs(state, argv, 4, &blockdev_filename, &transfer_list_value, &new_data_fn, &patch_data_fn) < 0) { return NULL; } @@ -267,7 +268,7 @@ Value* BlockImageUpdateFn(const char* name, State* state, int argc, Expr* argv[] ErrorAbort(state, "blockdev_filename argument to %s must be string", name); goto done; } - if (transfer_list->type != VAL_BLOB) { + if (transfer_list_value->type != VAL_BLOB) { ErrorAbort(state, "transfer_list argument to %s must be blob", name); goto done; } @@ -364,7 +365,19 @@ Value* BlockImageUpdateFn(const char* name, State* state, int argc, Expr* argv[] char* line; char* word; - line = strtok_r(transfer_list->data, "\n", &linesave); + // The data in transfer_list_value is not necessarily + // null-terminated, so we need to copy it to a new buffer and add + // the null that strtok_r will need. + transfer_list = malloc(transfer_list_value->size+1); + if (transfer_list == NULL) { + fprintf(stderr, "failed to allocate %zd bytes for transfer list\n", + transfer_list_value->size+1); + exit(1); + } + memcpy(transfer_list, transfer_list_value->data, transfer_list_value->size); + transfer_list[transfer_list_value->size] = '\0'; + + line = strtok_r(transfer_list, "\n", &linesave); // first line in transfer list is the version number; currently // there's only version 1. @@ -401,7 +414,7 @@ Value* BlockImageUpdateFn(const char* name, State* state, int argc, Expr* argv[] allocate(src->size * BLOCKSIZE, &buffer, &buffer_alloc); size_t p = 0; for (i = 0; i < src->count; ++i) { - check_lseek(fd, src->pos[i*2] * BLOCKSIZE, SEEK_SET); + check_lseek(fd, src->pos[i*2] * (off_t)BLOCKSIZE, SEEK_SET); size_t sz = (src->pos[i*2+1] - src->pos[i*2]) * BLOCKSIZE; readblock(fd, buffer+p, sz); p += sz; @@ -409,7 +422,7 @@ Value* BlockImageUpdateFn(const char* name, State* state, int argc, Expr* argv[] p = 0; for (i = 0; i < tgt->count; ++i) { - check_lseek(fd, tgt->pos[i*2] * BLOCKSIZE, SEEK_SET); + check_lseek(fd, tgt->pos[i*2] * (off_t)BLOCKSIZE, SEEK_SET); size_t sz = (tgt->pos[i*2+1] - tgt->pos[i*2]) * BLOCKSIZE; writeblock(fd, buffer+p, sz); p += sz; @@ -432,7 +445,7 @@ Value* BlockImageUpdateFn(const char* name, State* state, int argc, Expr* argv[] allocate(BLOCKSIZE, &buffer, &buffer_alloc); memset(buffer, 0, BLOCKSIZE); for (i = 0; i < tgt->count; ++i) { - check_lseek(fd, tgt->pos[i*2] * BLOCKSIZE, SEEK_SET); + check_lseek(fd, tgt->pos[i*2] * (off_t)BLOCKSIZE, SEEK_SET); for (j = tgt->pos[i*2]; j < tgt->pos[i*2+1]; ++j) { writeblock(fd, buffer, BLOCKSIZE); } @@ -457,7 +470,7 @@ Value* BlockImageUpdateFn(const char* name, State* state, int argc, Expr* argv[] rss.tgt = tgt; rss.p_block = 0; rss.p_remain = (tgt->pos[1] - tgt->pos[0]) * BLOCKSIZE; - check_lseek(fd, tgt->pos[0] * BLOCKSIZE, SEEK_SET); + check_lseek(fd, tgt->pos[0] * (off_t)BLOCKSIZE, SEEK_SET); pthread_mutex_lock(&nti.mu); nti.rss = &rss; @@ -491,7 +504,7 @@ Value* BlockImageUpdateFn(const char* name, State* state, int argc, Expr* argv[] allocate(src->size * BLOCKSIZE, &buffer, &buffer_alloc); size_t p = 0; for (i = 0; i < src->count; ++i) { - check_lseek(fd, src->pos[i*2] * BLOCKSIZE, SEEK_SET); + check_lseek(fd, src->pos[i*2] * (off_t)BLOCKSIZE, SEEK_SET); size_t sz = (src->pos[i*2+1] - src->pos[i*2]) * BLOCKSIZE; readblock(fd, buffer+p, sz); p += sz; @@ -507,7 +520,7 @@ Value* BlockImageUpdateFn(const char* name, State* state, int argc, Expr* argv[] rss.tgt = tgt; rss.p_block = 0; rss.p_remain = (tgt->pos[1] - tgt->pos[0]) * BLOCKSIZE; - check_lseek(fd, tgt->pos[0] * BLOCKSIZE, SEEK_SET); + check_lseek(fd, tgt->pos[0] * (off_t)BLOCKSIZE, SEEK_SET); if (style[0] == 'i') { // imgdiff ApplyImagePatch(buffer, src->size * BLOCKSIZE, @@ -541,9 +554,9 @@ Value* BlockImageUpdateFn(const char* name, State* state, int argc, Expr* argv[] for (i = 0; i < tgt->count; ++i) { uint64_t range[2]; // offset in bytes - range[0] = tgt->pos[i*2] * BLOCKSIZE; + range[0] = tgt->pos[i*2] * (uint64_t)BLOCKSIZE; // len in bytes - range[1] = (tgt->pos[i*2+1] - tgt->pos[i*2]) * BLOCKSIZE; + range[1] = (tgt->pos[i*2+1] - tgt->pos[i*2]) * (uint64_t)BLOCKSIZE; if (ioctl(fd, BLKDISCARD, &range) < 0) { printf(" blkdiscard failed: %s\n", strerror(errno)); @@ -568,8 +581,9 @@ Value* BlockImageUpdateFn(const char* name, State* state, int argc, Expr* argv[] printf("max alloc needed was %zu\n", buffer_alloc); done: + free(transfer_list); FreeValue(blockdev_filename); - FreeValue(transfer_list); + FreeValue(transfer_list_value); FreeValue(new_data_fn); FreeValue(patch_data_fn); return StringValue(success ? strdup("t") : strdup("")); @@ -606,7 +620,7 @@ Value* RangeSha1Fn(const char* name, State* state, int argc, Expr* argv[]) { int i, j; for (i = 0; i < rs->count; ++i) { - check_lseek(fd, rs->pos[i*2] * BLOCKSIZE, SEEK_SET); + check_lseek(fd, rs->pos[i*2] * (off_t)BLOCKSIZE, SEEK_SET); for (j = rs->pos[i*2]; j < rs->pos[i*2+1]; ++j) { readblock(fd, buffer, BLOCKSIZE); SHA_update(&ctx, buffer, BLOCKSIZE); -- cgit v1.2.3 From f9bc2a544d5189ef9279edb8b5d67913eec53855 Mon Sep 17 00:00:00 2001 From: Doug Zongker Date: Fri, 5 Sep 2014 08:22:12 -0700 Subject: create block map for all update packages on /data Always create the block map for packages on /data; don't only look at the encryptable/encrypted flags. Bug: 17395453 Change-Id: Iaa7643a32898328277841e324305b9419a9e071c --- uncrypt/uncrypt.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/uncrypt/uncrypt.c b/uncrypt/uncrypt.c index 07e5ae665..189fa57e1 100644 --- a/uncrypt/uncrypt.c +++ b/uncrypt/uncrypt.c @@ -160,8 +160,6 @@ char* parse_recovery_command_file() int count = 0; char temp[1024]; - - FILE* f = fopen(RECOVERY_COMMAND_FILE, "r"); if (f == NULL) { return NULL; @@ -405,16 +403,15 @@ int main(int argc, char** argv) ALOGI("encryptable: %s\n", encryptable ? "yes" : "no"); ALOGI(" encrypted: %s\n", encrypted ? "yes" : "no"); - if (!encryptable) { - // If the file is on a filesystem that doesn't support - // encryption (eg, /cache), then leave it alone. - // - // TODO: change this to be !encrypted -- if the file is on - // /data but /data isn't encrypted, we don't need to use the - // block map mechanism. We do for now so as to get more - // testing of it (since most dogfood devices aren't - // encrypted). - + // Recovery supports installing packages from 3 paths: /cache, + // /data, and /sdcard. (On a particular device, other locations + // may work, but those are three we actually expect.) + // + // On /data we want to convert the file to a block map so that we + // can read the package without mounting the partition. On /cache + // and /sdcard we leave the file alone. + if (strncmp(path, "/data/", 6) != 0) { + // path does not start with "/data/"; leave it alone. unlink(RECOVERY_COMMAND_FILE_TMP); } else { ALOGI("writing block map %s", map_file); -- cgit v1.2.3 From 8002104d3610d5f19e17b3b505b238af10129b0c Mon Sep 17 00:00:00 2001 From: Sungmin Choi Date: Wed, 10 Dec 2014 21:57:09 +0900 Subject: Add O_CREAT option for open Factory reset fails if there is no file, for example, RECOVERY_COMMAND_FILE_TMP. So create file as adding O_CREAT option if it does not exist. error log: --------- beginning of crash 12-10 02:35:17.190 3059 3059 F libc : Fatal signal 11 (SIGSEGV), code 1, fault addr 0x30 in tid 3059 (uncrypt) 12-10 02:35:17.296 766 1528 W NativeCrashListener: Couldn't find ProcessRecord for pid 3059 12-10 02:35:17.296 191 191 I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 12-10 02:35:17.296 191 191 E DEBUG : AM write failure (32 / Broken pipe) 12-10 02:35:17.296 191 191 I DEBUG : Build fingerprint: 'Android/aosp_hammerhead/hammerhead:5.1/LMP/hopemini12052127:userdebug/test-keys' 12-10 02:35:17.296 191 191 I DEBUG : Revision: '10' 12-10 02:35:17.297 191 191 I DEBUG : ABI: 'arm' 12-10 02:35:17.297 191 191 I DEBUG : pid: 3059, tid: 3059, name: uncrypt >>> /system/bin/uncrypt <<< 12-10 02:35:17.297 191 191 I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x30 12-10 02:35:17.302 191 191 I DEBUG : r0 00000001 r1 be94b690 r2 fffffe90 r3 b6fdbf7c 12-10 02:35:17.302 191 191 I DEBUG : r4 00000000 r5 00000000 r6 b6fd8ca4 r7 be94b67c 12-10 02:35:17.302 191 191 I DEBUG : r8 00000000 r9 ffffffff sl b6ff582b fp be94b68d 12-10 02:35:17.302 191 191 I DEBUG : ip b6fcfd08 sp be94b648 lr b6f98fe5 pc b6f98fe4 cpsr 20070030 12-10 02:35:17.303 191 191 I DEBUG : 12-10 02:35:17.303 191 191 I DEBUG : backtrace: 12-10 02:35:17.303 191 191 I DEBUG : #00 pc 00032fe4 /system/lib/libc.so (fputs+29) 12-10 02:35:17.303 191 191 I DEBUG : #01 pc 000016a1 /system/bin/uncrypt 12-10 02:35:17.303 191 191 I DEBUG : #02 pc 0000114b /system/bin/uncrypt 12-10 02:35:17.303 191 191 I DEBUG : #03 pc 00012df5 /system/lib/libc.so (__libc_init+44) 12-10 02:35:17.303 191 191 I DEBUG : #04 pc 000013cc /system/bin/uncrypt 12-10 02:35:17.325 191 191 I DEBUG : 12-10 02:35:17.325 191 191 I DEBUG : Tombstone written to: /data/tombstones/tombstone_00 Bug: 18709330 Change-Id: Ib5dccdd366e829049938a188ea5f98d9e4e282db --- uncrypt/uncrypt.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/uncrypt/uncrypt.c b/uncrypt/uncrypt.c index 361c80483..7fb0989a7 100644 --- a/uncrypt/uncrypt.c +++ b/uncrypt/uncrypt.c @@ -164,7 +164,11 @@ char* parse_recovery_command_file() if (f == NULL) { return NULL; } - int fd = open(RECOVERY_COMMAND_FILE_TMP, O_WRONLY | O_SYNC); + int fd = open(RECOVERY_COMMAND_FILE_TMP, O_WRONLY | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR); + if (fd < 0) { + ALOGE("failed to open %s\n", RECOVERY_COMMAND_FILE_TMP); + return NULL; + } FILE* fo = fdopen(fd, "w"); while (fgets(temp, sizeof(temp), f)) { @@ -192,7 +196,11 @@ int produce_block_map(const char* path, const char* map_file, const char* blk_de struct stat sb; int ret; - int mapfd = open(map_file, O_WRONLY | O_SYNC); + int mapfd = open(map_file, O_WRONLY | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR); + if (mapfd < 0) { + ALOGE("failed to open %s\n", map_file); + return -1; + } FILE* mapf = fdopen(mapfd, "w"); ret = stat(path, &sb); -- cgit v1.2.3