Control fault injection with config files instead of build flags
am: ff6df89
* commit 'ff6df890a2a01bf3bf56d3f430b17a5ef69055cf':
Control fault injection with config files instead of build flags
diff --git a/Android.mk b/Android.mk
index 5b488ca..c2f98c6 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,18 +14,20 @@
LOCAL_PATH := $(call my-dir)
+# libfusesideload (static library)
+# ===============================
include $(CLEAR_VARS)
LOCAL_SRC_FILES := fuse_sideload.cpp
LOCAL_CLANG := true
LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter
LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
-
LOCAL_MODULE := libfusesideload
-
LOCAL_STATIC_LIBRARIES := libcutils libc libmincrypt
include $(BUILD_STATIC_LIBRARY)
+# recovery (static executable)
+# ===============================
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
@@ -103,7 +105,8 @@
include $(BUILD_EXECUTABLE)
-# All the APIs for testing
+# libverifier (static library)
+# ===============================
include $(CLEAR_VARS)
LOCAL_CLANG := true
LOCAL_MODULE := libverifier
diff --git a/applypatch/Android.mk b/applypatch/Android.mk
index 887a570..9e64718 100644
--- a/applypatch/Android.mk
+++ b/applypatch/Android.mk
@@ -14,61 +14,83 @@
LOCAL_PATH := $(call my-dir)
+# libapplypatch (static library)
+# ===============================
include $(CLEAR_VARS)
-
LOCAL_CLANG := true
-LOCAL_SRC_FILES := applypatch.cpp bspatch.cpp freecache.cpp imgpatch.cpp utils.cpp
+LOCAL_SRC_FILES := \
+ applypatch.cpp \
+ bspatch.cpp \
+ freecache.cpp \
+ imgpatch.cpp \
+ utils.cpp
LOCAL_MODULE := libapplypatch
LOCAL_MODULE_TAGS := eng
-LOCAL_C_INCLUDES += bootable/recovery
-LOCAL_STATIC_LIBRARIES += libbase libotafault libmtdutils libcrypto_static libbz libz
-
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/include \
+ bootable/recovery
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_STATIC_LIBRARIES += \
+ libotafault \
+ libmtdutils \
+ libbase \
+ libcrypto_static \
+ libbz \
+ libz
include $(BUILD_STATIC_LIBRARY)
+# libimgpatch (static library)
+# ===============================
include $(CLEAR_VARS)
-
LOCAL_CLANG := true
LOCAL_SRC_FILES := bspatch.cpp imgpatch.cpp utils.cpp
LOCAL_MODULE := libimgpatch
-LOCAL_C_INCLUDES += bootable/recovery
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/include \
+ bootable/recovery
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
LOCAL_STATIC_LIBRARIES += libcrypto_static libbz libz
-
include $(BUILD_STATIC_LIBRARY)
-ifeq ($(HOST_OS),linux)
+# libimgpatch (host static library)
+# ===============================
include $(CLEAR_VARS)
-
LOCAL_CLANG := true
LOCAL_SRC_FILES := bspatch.cpp imgpatch.cpp utils.cpp
LOCAL_MODULE := libimgpatch
-LOCAL_C_INCLUDES += bootable/recovery
+LOCAL_MODULE_HOST_OS := linux
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/include \
+ bootable/recovery
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
LOCAL_STATIC_LIBRARIES += libcrypto_static libbz libz
-
include $(BUILD_HOST_STATIC_LIBRARY)
-endif # HOST_OS == linux
+# applypatch (executable)
+# ===============================
include $(CLEAR_VARS)
-
LOCAL_CLANG := true
LOCAL_SRC_FILES := main.cpp
LOCAL_MODULE := applypatch
LOCAL_C_INCLUDES += bootable/recovery
-LOCAL_STATIC_LIBRARIES += libapplypatch libbase libotafault libmtdutils libcrypto_static libbz \
- libedify \
-
+LOCAL_STATIC_LIBRARIES += \
+ libapplypatch \
+ libbase \
+ libedify \
+ libotafault \
+ libminzip \
+ libmtdutils \
+ libcrypto_static \
+ libbz
LOCAL_SHARED_LIBRARIES += libz libcutils libc
-
include $(BUILD_EXECUTABLE)
+# imgdiff (host static executable)
+# ===============================
include $(CLEAR_VARS)
-
LOCAL_CLANG := true
LOCAL_SRC_FILES := imgdiff.cpp utils.cpp bsdiff.cpp
LOCAL_MODULE := imgdiff
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-LOCAL_C_INCLUDES += external/zlib external/bzip2
LOCAL_STATIC_LIBRARIES += libz libbz
-
+LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_HOST_EXECUTABLE)
diff --git a/applypatch/Makefile b/applypatch/Makefile
new file mode 100644
index 0000000..fb49843
--- /dev/null
+++ b/applypatch/Makefile
@@ -0,0 +1,33 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This file is for building imgdiff in Chrome OS.
+
+CPPFLAGS += -iquote.. -Iinclude
+CXXFLAGS += -std=c++11 -O3 -Wall -Werror
+LDLIBS += -lbz2 -lz
+
+.PHONY: all clean
+
+all: imgdiff libimgpatch.a
+
+clean:
+ rm -f *.o imgdiff libimgpatch.a
+
+imgdiff: imgdiff.o bsdiff.o utils.o
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDLIBS) -o $@ $^
+
+libimgpatch.a utils.o: CXXFLAGS += -fPIC
+libimgpatch.a: imgpatch.o bspatch.o utils.o
+ ${AR} rcs $@ $^
diff --git a/applypatch/applypatch.cpp b/applypatch/applypatch.cpp
index 7985fc0..c8594c2 100644
--- a/applypatch/applypatch.cpp
+++ b/applypatch/applypatch.cpp
@@ -31,7 +31,7 @@
#include <android-base/strings.h>
#include "openssl/sha.h"
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
#include "mtdutils/mtdutils.h"
#include "edify/expr.h"
#include "ota_io.h"
@@ -77,7 +77,7 @@
size_t bytes_read = ota_fread(data.data(), 1, data.size(), f);
if (bytes_read != data.size()) {
- printf("short read of \"%s\" (%zu bytes of %zd)\n", filename, bytes_read, data.size());
+ printf("short read of \"%s\" (%zu bytes of %zu)\n", filename, bytes_read, data.size());
ota_fclose(f);
return -1;
}
@@ -897,7 +897,7 @@
} else {
// We write the decoded output to "<tgt-file>.patch".
output_fd = ota_open(tmp_target_filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_SYNC,
- S_IRUSR | S_IWUSR);
+ S_IRUSR | S_IWUSR);
if (output_fd < 0) {
printf("failed to open output file %s: %s\n", tmp_target_filename.c_str(),
strerror(errno));
diff --git a/applypatch/bsdiff.cpp b/applypatch/bsdiff.cpp
index 55dbe5c..cca1b32 100644
--- a/applypatch/bsdiff.cpp
+++ b/applypatch/bsdiff.cpp
@@ -224,7 +224,6 @@
int bsdiff(u_char* old, off_t oldsize, off_t** IP, u_char* newdata, off_t newsize,
const char* patch_filename)
{
- int fd;
off_t *I;
off_t scan,pos,len;
off_t lastscan,lastpos,lastoffset;
diff --git a/applypatch/bspatch.cpp b/applypatch/bspatch.cpp
index ebb55f1..a4945da 100644
--- a/applypatch/bspatch.cpp
+++ b/applypatch/bspatch.cpp
@@ -30,7 +30,7 @@
#include <bzlib.h>
#include "openssl/sha.h"
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
void ShowBSDiffLicense() {
puts("The bsdiff library used herein is:\n"
@@ -182,7 +182,6 @@
off_t oldpos = 0, newpos = 0;
off_t ctrl[3];
- off_t len_read;
int i;
unsigned char buf[24];
while (newpos < new_size) {
diff --git a/applypatch/freecache.cpp b/applypatch/freecache.cpp
index c84f427..331cae2 100644
--- a/applypatch/freecache.cpp
+++ b/applypatch/freecache.cpp
@@ -32,7 +32,7 @@
#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
static int EliminateOpenFiles(std::set<std::string>* files) {
std::unique_ptr<DIR, decltype(&closedir)> d(opendir("/proc"), closedir);
diff --git a/applypatch/imgdiff.cpp b/applypatch/imgdiff.cpp
index f22502e..2aa4a68 100644
--- a/applypatch/imgdiff.cpp
+++ b/applypatch/imgdiff.cpp
@@ -407,7 +407,6 @@
while (pos < sz) {
unsigned char* p = img+pos;
- bool processed_deflate = false;
if (sz - pos >= 4 &&
p[0] == 0x1f && p[1] == 0x8b &&
p[2] == 0x08 && // deflate compression
@@ -461,28 +460,27 @@
strm.next_out = curr->data + curr->len;
ret = inflate(&strm, Z_NO_FLUSH);
if (ret < 0) {
- if (!processed_deflate) {
- // This is the first chunk, assume that it's just a spurious
- // gzip header instead of a real one.
- break;
- }
- printf("Error: inflate failed [%s] at file offset [%zu]\n"
- "imgdiff only supports gzip kernel compression,"
- " did you try CONFIG_KERNEL_LZO?\n",
+ printf("Warning: inflate failed [%s] at offset [%zu],"
+ " treating as a normal chunk\n",
strm.msg, chunk_offset);
- free(img);
- return NULL;
+ break;
}
curr->len = allocated - strm.avail_out;
if (strm.avail_out == 0) {
allocated *= 2;
curr->data = reinterpret_cast<unsigned char*>(realloc(curr->data, allocated));
}
- processed_deflate = true;
} while (ret != Z_STREAM_END);
curr->deflate_len = sz - strm.avail_in - pos;
inflateEnd(&strm);
+
+ if (ret < 0) {
+ free(curr->data);
+ *num_chunks -= 2;
+ continue;
+ }
+
pos += curr->deflate_len;
p += curr->deflate_len;
++curr;
@@ -598,7 +596,6 @@
return -1;
}
- size_t p = 0;
unsigned char* out = reinterpret_cast<unsigned char*>(malloc(BUFFER_SIZE));
// We only check two combinations of encoder parameters: level 6
@@ -844,7 +841,6 @@
}
if (argc != 4) {
- usage:
printf("usage: %s [-z] [-b <bonus-file>] <src-img> <tgt-img> <patch-file>\n",
argv[0]);
return 2;
diff --git a/applypatch/imgpatch.cpp b/applypatch/imgpatch.cpp
index 8824038..4251c01 100644
--- a/applypatch/imgpatch.cpp
+++ b/applypatch/imgpatch.cpp
@@ -28,7 +28,7 @@
#include "zlib.h"
#include "openssl/sha.h"
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
#include "imgdiff.h"
#include "utils.h"
@@ -130,6 +130,7 @@
size_t src_len = Read8(deflate_header+8);
size_t patch_offset = Read8(deflate_header+16);
size_t expanded_len = Read8(deflate_header+24);
+ size_t target_len = Read8(deflate_header+32);
int level = Read4(deflate_header+40);
int method = Read4(deflate_header+44);
int windowBits = Read4(deflate_header+48);
@@ -195,6 +196,11 @@
&uncompressed_target_data) != 0) {
return -1;
}
+ if (uncompressed_target_data.size() != target_len) {
+ printf("expected target len to be %zu, but it's %zu\n",
+ target_len, uncompressed_target_data.size());
+ return -1;
+ }
// Now compress the target data and append it to the output.
diff --git a/applypatch/applypatch.h b/applypatch/include/applypatch/applypatch.h
similarity index 99%
rename from applypatch/applypatch.h
rename to applypatch/include/applypatch/applypatch.h
index f392c55..9ee39d2 100644
--- a/applypatch/applypatch.h
+++ b/applypatch/include/applypatch/applypatch.h
@@ -17,6 +17,7 @@
#ifndef _APPLYPATCH_H
#define _APPLYPATCH_H
+#include <stdint.h>
#include <sys/stat.h>
#include <vector>
diff --git a/applypatch/libimgpatch.pc b/applypatch/libimgpatch.pc
new file mode 100644
index 0000000..e500293
--- /dev/null
+++ b/applypatch/libimgpatch.pc
@@ -0,0 +1,6 @@
+# This file is for libimgpatch in Chrome OS.
+
+Name: libimgpatch
+Description: Apply imgdiff patch
+Version: 0.0.1
+Libs: -limgpatch -lbz2 -lz
diff --git a/applypatch/main.cpp b/applypatch/main.cpp
index 9013760..0ff8cbf 100644
--- a/applypatch/main.cpp
+++ b/applypatch/main.cpp
@@ -22,7 +22,7 @@
#include <memory>
#include <vector>
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
#include "edify/expr.h"
#include "openssl/sha.h"
diff --git a/install.cpp b/install.cpp
index 8a82d7b..144a353 100644
--- a/install.cpp
+++ b/install.cpp
@@ -124,20 +124,20 @@
// - the name of the package zip file.
//
- const char** args = (const char**)malloc(sizeof(char*) * 5);
+ const char* args[5];
args[0] = binary;
args[1] = EXPAND(RECOVERY_API_VERSION); // defined in Android.mk
- char* temp = (char*)malloc(10);
- sprintf(temp, "%d", pipefd[1]);
+ char temp[16];
+ snprintf(temp, sizeof(temp), "%d", pipefd[1]);
args[2] = temp;
- args[3] = (char*)path;
+ args[3] = path;
args[4] = NULL;
pid_t pid = fork();
if (pid == 0) {
umask(022);
close(pipefd[0]);
- execv(binary, (char* const*)args);
+ execv(binary, const_cast<char**>(args));
fprintf(stdout, "E:Can't run %s (%s)\n", binary, strerror(errno));
_exit(-1);
}
diff --git a/minui/resources.cpp b/minui/resources.cpp
index 63a0dff..8489d60 100644
--- a/minui/resources.cpp
+++ b/minui/resources.cpp
@@ -28,6 +28,7 @@
#include <linux/fb.h>
#include <linux/kd.h>
+#include <vector>
#include <png.h>
#include "minui.h"
@@ -282,7 +283,7 @@
goto exit;
}
- surface = reinterpret_cast<GRSurface**>(malloc(*frames * sizeof(GRSurface*)));
+ surface = reinterpret_cast<GRSurface**>(calloc(*frames, sizeof(GRSurface*)));
if (surface == NULL) {
result = -8;
goto exit;
@@ -317,7 +318,7 @@
if (result < 0) {
if (surface) {
for (int i = 0; i < *frames; ++i) {
- if (surface[i]) free(surface[i]);
+ free(surface[i]);
}
free(surface);
}
@@ -398,18 +399,13 @@
png_infop info_ptr = NULL;
png_uint_32 width, height;
png_byte channels;
- unsigned char* row;
png_uint_32 y;
+ std::vector<unsigned char> row;
*pSurface = NULL;
if (locale == NULL) {
- surface = malloc_surface(0);
- surface->width = 0;
- surface->height = 0;
- surface->row_bytes = 0;
- surface->pixel_bytes = 1;
- goto exit;
+ return result;
}
result = open_png(name, &png_ptr, &info_ptr, &width, &height, &channels);
@@ -420,13 +416,13 @@
goto exit;
}
- row = reinterpret_cast<unsigned char*>(malloc(width));
+ row.resize(width);
for (y = 0; y < height; ++y) {
- png_read_row(png_ptr, row, NULL);
+ png_read_row(png_ptr, row.data(), NULL);
int w = (row[1] << 8) | row[0];
int h = (row[3] << 8) | row[2];
- int len = row[4];
- char* loc = (char*)row+5;
+ __unused int len = row[4];
+ char* loc = reinterpret_cast<char*>(&row[5]);
if (y+1+h >= height || matches_locale(loc, locale)) {
printf(" %20s: %s (%d x %d @ %d)\n", name, loc, w, h, y);
@@ -443,8 +439,8 @@
int i;
for (i = 0; i < h; ++i, ++y) {
- png_read_row(png_ptr, row, NULL);
- memcpy(surface->data + i*w, row, w);
+ png_read_row(png_ptr, row.data(), NULL);
+ memcpy(surface->data + i*w, row.data(), w);
}
*pSurface = reinterpret_cast<GRSurface*>(surface);
@@ -452,7 +448,7 @@
} else {
int i;
for (i = 0; i < h; ++i, ++y) {
- png_read_row(png_ptr, row, NULL);
+ png_read_row(png_ptr, row.data(), NULL);
}
}
}
diff --git a/minzip/Android.mk b/minzip/Android.mk
index 22eabfb..3d36fd6 100644
--- a/minzip/Android.mk
+++ b/minzip/Android.mk
@@ -4,7 +4,7 @@
LOCAL_SRC_FILES := \
Hash.c \
SysUtil.c \
- DirUtil.c \
+ DirUtil.cpp \
Inlines.c \
Zip.c
diff --git a/minzip/DirUtil.c b/minzip/DirUtil.cpp
similarity index 78%
rename from minzip/DirUtil.c
rename to minzip/DirUtil.cpp
index 97cb2e0..823b6ed 100644
--- a/minzip/DirUtil.c
+++ b/minzip/DirUtil.cpp
@@ -24,6 +24,8 @@
#include <dirent.h>
#include <limits.h>
+#include <string>
+
#include "DirUtil.h"
typedef enum { DMISSING, DDIR, DILLEGAL } DirStatus;
@@ -66,43 +68,25 @@
errno = ENOENT;
return -1;
}
-
- /* Allocate a path that we can modify; stick a slash on
- * the end to make things easier.
- */
- size_t pathLen = strlen(path);
- char *cpath = (char *)malloc(pathLen + 2);
- if (cpath == NULL) {
- errno = ENOMEM;
- return -1;
- }
- memcpy(cpath, path, pathLen);
+ // Allocate a path that we can modify; stick a slash on
+ // the end to make things easier.
+ std::string cpath = path;
if (stripFileName) {
- /* Strip everything after the last slash.
- */
- char *c = cpath + pathLen - 1;
- while (c != cpath && *c != '/') {
- c--;
- }
- if (c == cpath) {
- //xxx test this path
- /* No directory component. Act like the path was empty.
- */
+ // Strip everything after the last slash.
+ size_t pos = cpath.rfind('/');
+ if (pos == std::string::npos) {
errno = ENOENT;
- free(cpath);
return -1;
}
- c[1] = '\0'; // Terminate after the slash we found.
+ cpath.resize(pos + 1);
} else {
- /* Make sure that the path ends in a slash.
- */
- cpath[pathLen] = '/';
- cpath[pathLen + 1] = '\0';
+ // Make sure that the path ends in a slash.
+ cpath.push_back('/');
}
/* See if it already exists.
*/
- ds = getPathDirStatus(cpath);
+ ds = getPathDirStatus(cpath.c_str());
if (ds == DDIR) {
return 0;
} else if (ds == DILLEGAL) {
@@ -112,7 +96,8 @@
/* Walk up the path from the root and make each level.
* If a directory already exists, no big deal.
*/
- char *p = cpath;
+ const char *path_start = &cpath[0];
+ char *p = &cpath[0];
while (*p != '\0') {
/* Skip any slashes, watching out for the end of the string.
*/
@@ -135,12 +120,11 @@
/* Check this part of the path and make a new directory
* if necessary.
*/
- ds = getPathDirStatus(cpath);
+ ds = getPathDirStatus(path_start);
if (ds == DILLEGAL) {
/* Could happen if some other process/thread is
* messing with the filesystem.
*/
- free(cpath);
return -1;
} else if (ds == DMISSING) {
int err;
@@ -148,11 +132,11 @@
char *secontext = NULL;
if (sehnd) {
- selabel_lookup(sehnd, &secontext, cpath, mode);
+ selabel_lookup(sehnd, &secontext, path_start, mode);
setfscreatecon(secontext);
}
- err = mkdir(cpath, mode);
+ err = mkdir(path_start, mode);
if (secontext) {
freecon(secontext);
@@ -160,22 +144,17 @@
}
if (err != 0) {
- free(cpath);
return -1;
}
- if (timestamp != NULL && utime(cpath, timestamp)) {
- free(cpath);
+ if (timestamp != NULL && utime(path_start, timestamp)) {
return -1;
}
}
// else, this directory already exists.
-
- /* Repair the path and continue.
- */
+
+ // Repair the path and continue.
*p = '/';
}
- free(cpath);
-
return 0;
}
diff --git a/minzip/Zip.c b/minzip/Zip.c
index bdb565c..0f89835 100644
--- a/minzip/Zip.c
+++ b/minzip/Zip.c
@@ -91,7 +91,7 @@
static void dumpEntry(const ZipEntry* pEntry)
{
LOGI(" %p '%.*s'\n", pEntry->fileName,pEntry->fileNameLen,pEntry->fileName);
- LOGI(" off=%ld comp=%ld uncomp=%ld how=%d\n", pEntry->offset,
+ LOGI(" off=%u comp=%u uncomp=%u how=%d\n", pEntry->offset,
pEntry->compLen, pEntry->uncompLen, pEntry->compression);
}
#endif
@@ -505,13 +505,11 @@
const ZipEntry *pEntry, ProcessZipEntryContentsFunction processFunction,
void *cookie)
{
- long result = -1;
+ bool success = false;
+ unsigned long totalOut = 0;
unsigned char procBuf[32 * 1024];
z_stream zstream;
int zerr;
- long compRemaining;
-
- compRemaining = pEntry->compLen;
/*
* Initialize the zlib stream.
@@ -572,16 +570,17 @@
assert(zerr == Z_STREAM_END); /* other errors should've been caught */
// success!
- result = zstream.total_out;
+ totalOut = zstream.total_out;
+ success = true;
z_bail:
inflateEnd(&zstream); /* free up any allocated structures */
bail:
- if (result != pEntry->uncompLen) {
- if (result != -1) // error already shown?
- LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
- result, pEntry->uncompLen);
+ if (totalOut != pEntry->uncompLen) {
+ if (success) { // error already shown?
+ LOGW("Size mismatch on inflated file (%lu vs %u)\n", totalOut, pEntry->uncompLen);
+ }
return false;
}
return true;
@@ -759,7 +758,7 @@
*/
needLen = helper->targetDirLen + 1 +
pEntry->fileNameLen - helper->zipDirLen + 1;
- if (needLen > helper->bufLen) {
+ if (firstTime || needLen > helper->bufLen) {
char *newBuf;
needLen *= 2;
diff --git a/minzip/Zip.h b/minzip/Zip.h
index 86d8db5..e6b19e1 100644
--- a/minzip/Zip.h
+++ b/minzip/Zip.h
@@ -32,9 +32,9 @@
typedef struct ZipEntry {
unsigned int fileNameLen;
const char* fileName; // not null-terminated
- long offset;
- long compLen;
- long uncompLen;
+ uint32_t offset;
+ uint32_t compLen;
+ uint32_t uncompLen;
int compression;
long modTime;
long crc32;
@@ -85,10 +85,10 @@
const ZipEntry* mzFindZipEntry(const ZipArchive* pArchive,
const char* entryName);
-INLINE long mzGetZipEntryOffset(const ZipEntry* pEntry) {
+INLINE uint32_t mzGetZipEntryOffset(const ZipEntry* pEntry) {
return pEntry->offset;
}
-INLINE long mzGetZipEntryUncompLen(const ZipEntry* pEntry) {
+INLINE uint32_t mzGetZipEntryUncompLen(const ZipEntry* pEntry) {
return pEntry->uncompLen;
}
diff --git a/otafault/Android.mk b/otafault/Android.mk
index 7468de6..33308c7 100644
--- a/otafault/Android.mk
+++ b/otafault/Android.mk
@@ -31,6 +31,8 @@
include $(BUILD_STATIC_LIBRARY)
+# otafault_test (static executable)
+# ===============================
include $(CLEAR_VARS)
LOCAL_SRC_FILES := config.cpp ota_io.cpp test.cpp
diff --git a/otafault/ota_io.cpp b/otafault/ota_io.cpp
index 0445853..94be815 100644
--- a/otafault/ota_io.cpp
+++ b/otafault/ota_io.cpp
@@ -92,6 +92,7 @@
}
}
size_t status = fread(ptr, size, nitems, stream);
+ // If I/O error occurs, set the retry-update flag.
if (status != nitems && errno == EIO) {
have_eio_error = true;
}
diff --git a/tests/component/verifier_test.cpp b/tests/component/verifier_test.cpp
index 73f6ac9..c533b03 100644
--- a/tests/component/verifier_test.cpp
+++ b/tests/component/verifier_test.cpp
@@ -133,13 +133,13 @@
void Init() { }
void SetStage(int, int) { }
void SetLocale(const char*) { }
- void SetBackground(Icon icon) { }
+ void SetBackground(Icon /*icon*/) { }
- void SetProgressType(ProgressType determinate) { }
- void ShowProgress(float portion, float seconds) { }
- void SetProgress(float fraction) { }
+ void SetProgressType(ProgressType /*determinate*/) { }
+ void ShowProgress(float /*portion*/, float /*seconds*/) { }
+ void SetProgress(float /*fraction*/) { }
- void ShowText(bool visible) { }
+ void ShowText(bool /*visible*/) { }
bool IsTextVisible() { return false; }
bool WasTextEverVisible() { return false; }
void Print(const char* fmt, ...) {
@@ -156,9 +156,10 @@
}
void ShowFile(const char*) { }
- void StartMenu(const char* const * headers, const char* const * items,
- int initial_selection) { }
- int SelectMenu(int sel) { return 0; }
+ void StartMenu(const char* const* /*headers*/,
+ const char* const* /*items*/,
+ int /*initial_selection*/) { }
+ int SelectMenu(int /*sel*/) { return 0; }
void EndMenu() { }
};
diff --git a/tools/dumpkey/Android.mk b/tools/dumpkey/Android.mk
new file mode 100644
index 0000000..3154914
--- /dev/null
+++ b/tools/dumpkey/Android.mk
@@ -0,0 +1,22 @@
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := dumpkey
+LOCAL_SRC_FILES := DumpPublicKey.java
+LOCAL_JAR_MANIFEST := DumpPublicKey.mf
+LOCAL_STATIC_JAVA_LIBRARIES := bouncycastle-host
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/dumpkey/DumpPublicKey.java b/tools/dumpkey/DumpPublicKey.java
new file mode 100644
index 0000000..3eb1398
--- /dev/null
+++ b/tools/dumpkey/DumpPublicKey.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.dumpkey;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+import java.io.FileInputStream;
+import java.math.BigInteger;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.KeyStore;
+import java.security.Key;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.ECPoint;
+
+/**
+ * Command line tool to extract RSA public keys from X.509 certificates
+ * and output source code with data initializers for the keys.
+ * @hide
+ */
+class DumpPublicKey {
+ /**
+ * @param key to perform sanity checks on
+ * @return version number of key. Supported versions are:
+ * 1: 2048-bit RSA key with e=3 and SHA-1 hash
+ * 2: 2048-bit RSA key with e=65537 and SHA-1 hash
+ * 3: 2048-bit RSA key with e=3 and SHA-256 hash
+ * 4: 2048-bit RSA key with e=65537 and SHA-256 hash
+ * @throws Exception if the key has the wrong size or public exponent
+ */
+ static int checkRSA(RSAPublicKey key, boolean useSHA256) throws Exception {
+ BigInteger pubexp = key.getPublicExponent();
+ BigInteger modulus = key.getModulus();
+ int version;
+
+ if (pubexp.equals(BigInteger.valueOf(3))) {
+ version = useSHA256 ? 3 : 1;
+ } else if (pubexp.equals(BigInteger.valueOf(65537))) {
+ version = useSHA256 ? 4 : 2;
+ } else {
+ throw new Exception("Public exponent should be 3 or 65537 but is " +
+ pubexp.toString(10) + ".");
+ }
+
+ if (modulus.bitLength() != 2048) {
+ throw new Exception("Modulus should be 2048 bits long but is " +
+ modulus.bitLength() + " bits.");
+ }
+
+ return version;
+ }
+
+ /**
+ * @param key to perform sanity checks on
+ * @return version number of key. Supported versions are:
+ * 5: 256-bit EC key with curve NIST P-256
+ * @throws Exception if the key has the wrong size or public exponent
+ */
+ static int checkEC(ECPublicKey key) throws Exception {
+ if (key.getParams().getCurve().getField().getFieldSize() != 256) {
+ throw new Exception("Curve must be NIST P-256");
+ }
+
+ return 5;
+ }
+
+ /**
+ * Perform sanity check on public key.
+ */
+ static int check(PublicKey key, boolean useSHA256) throws Exception {
+ if (key instanceof RSAPublicKey) {
+ return checkRSA((RSAPublicKey) key, useSHA256);
+ } else if (key instanceof ECPublicKey) {
+ if (!useSHA256) {
+ throw new Exception("Must use SHA-256 with EC keys!");
+ }
+ return checkEC((ECPublicKey) key);
+ } else {
+ throw new Exception("Unsupported key class: " + key.getClass().getName());
+ }
+ }
+
+ /**
+ * @param key to output
+ * @return a String representing this public key. If the key is a
+ * version 1 key, the string will be a C initializer; this is
+ * not true for newer key versions.
+ */
+ static String printRSA(RSAPublicKey key, boolean useSHA256) throws Exception {
+ int version = check(key, useSHA256);
+
+ BigInteger N = key.getModulus();
+
+ StringBuilder result = new StringBuilder();
+
+ int nwords = N.bitLength() / 32; // # of 32 bit integers in modulus
+
+ if (version > 1) {
+ result.append("v");
+ result.append(Integer.toString(version));
+ result.append(" ");
+ }
+
+ result.append("{");
+ result.append(nwords);
+
+ BigInteger B = BigInteger.valueOf(0x100000000L); // 2^32
+ BigInteger N0inv = B.subtract(N.modInverse(B)); // -1 / N[0] mod 2^32
+
+ result.append(",0x");
+ result.append(N0inv.toString(16));
+
+ BigInteger R = BigInteger.valueOf(2).pow(N.bitLength());
+ BigInteger RR = R.multiply(R).mod(N); // 2^4096 mod N
+
+ // Write out modulus as little endian array of integers.
+ result.append(",{");
+ for (int i = 0; i < nwords; ++i) {
+ long n = N.mod(B).longValue();
+ result.append(n);
+
+ if (i != nwords - 1) {
+ result.append(",");
+ }
+
+ N = N.divide(B);
+ }
+ result.append("}");
+
+ // Write R^2 as little endian array of integers.
+ result.append(",{");
+ for (int i = 0; i < nwords; ++i) {
+ long rr = RR.mod(B).longValue();
+ result.append(rr);
+
+ if (i != nwords - 1) {
+ result.append(",");
+ }
+
+ RR = RR.divide(B);
+ }
+ result.append("}");
+
+ result.append("}");
+ return result.toString();
+ }
+
+ /**
+ * @param key to output
+ * @return a String representing this public key. If the key is a
+ * version 1 key, the string will be a C initializer; this is
+ * not true for newer key versions.
+ */
+ static String printEC(ECPublicKey key) throws Exception {
+ int version = checkEC(key);
+
+ StringBuilder result = new StringBuilder();
+
+ result.append("v");
+ result.append(Integer.toString(version));
+ result.append(" ");
+
+ BigInteger X = key.getW().getAffineX();
+ BigInteger Y = key.getW().getAffineY();
+ int nbytes = key.getParams().getCurve().getField().getFieldSize() / 8; // # of 32 bit integers in X coordinate
+
+ result.append("{");
+ result.append(nbytes);
+
+ BigInteger B = BigInteger.valueOf(0x100L); // 2^8
+
+ // Write out Y coordinate as array of characters.
+ result.append(",{");
+ for (int i = 0; i < nbytes; ++i) {
+ long n = X.mod(B).longValue();
+ result.append(n);
+
+ if (i != nbytes - 1) {
+ result.append(",");
+ }
+
+ X = X.divide(B);
+ }
+ result.append("}");
+
+ // Write out Y coordinate as array of characters.
+ result.append(",{");
+ for (int i = 0; i < nbytes; ++i) {
+ long n = Y.mod(B).longValue();
+ result.append(n);
+
+ if (i != nbytes - 1) {
+ result.append(",");
+ }
+
+ Y = Y.divide(B);
+ }
+ result.append("}");
+
+ result.append("}");
+ return result.toString();
+ }
+
+ static String print(PublicKey key, boolean useSHA256) throws Exception {
+ if (key instanceof RSAPublicKey) {
+ return printRSA((RSAPublicKey) key, useSHA256);
+ } else if (key instanceof ECPublicKey) {
+ return printEC((ECPublicKey) key);
+ } else {
+ throw new Exception("Unsupported key class: " + key.getClass().getName());
+ }
+ }
+
+ public static void main(String[] args) {
+ if (args.length < 1) {
+ System.err.println("Usage: DumpPublicKey certfile ... > source.c");
+ System.exit(1);
+ }
+ Security.addProvider(new BouncyCastleProvider());
+ try {
+ for (int i = 0; i < args.length; i++) {
+ FileInputStream input = new FileInputStream(args[i]);
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ X509Certificate cert = (X509Certificate) cf.generateCertificate(input);
+
+ boolean useSHA256 = false;
+ String sigAlg = cert.getSigAlgName();
+ if ("SHA1withRSA".equals(sigAlg) || "MD5withRSA".equals(sigAlg)) {
+ // SignApk has historically accepted "MD5withRSA"
+ // certificates, but treated them as "SHA1withRSA"
+ // anyway. Continue to do so for backwards
+ // compatibility.
+ useSHA256 = false;
+ } else if ("SHA256withRSA".equals(sigAlg) || "SHA256withECDSA".equals(sigAlg)) {
+ useSHA256 = true;
+ } else {
+ System.err.println(args[i] + ": unsupported signature algorithm \"" +
+ sigAlg + "\"");
+ System.exit(1);
+ }
+
+ PublicKey key = cert.getPublicKey();
+ check(key, useSHA256);
+ System.out.print(print(key, useSHA256));
+ System.out.println(i < args.length - 1 ? "," : "");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ System.exit(0);
+ }
+}
diff --git a/tools/dumpkey/DumpPublicKey.mf b/tools/dumpkey/DumpPublicKey.mf
new file mode 100644
index 0000000..7bb3bc8
--- /dev/null
+++ b/tools/dumpkey/DumpPublicKey.mf
@@ -0,0 +1 @@
+Main-Class: com.android.dumpkey.DumpPublicKey
diff --git a/updater/Android.mk b/updater/Android.mk
index d7aa613..47c56cc 100644
--- a/updater/Android.mk
+++ b/updater/Android.mk
@@ -14,26 +14,50 @@
LOCAL_PATH := $(call my-dir)
-updater_src_files := \
- install.cpp \
- blockimg.cpp \
- updater.cpp
-
-#
-# Build a statically-linked binary to include in OTA packages
-#
+# updater (static executable)
+# ===============================
+# Build a statically-linked binary to include in OTA packages.
include $(CLEAR_VARS)
-# Build only in eng, so we don't end up with a copy of this in /system
-# on user builds. (TODO: find a better way to build device binaries
-# needed only for OTA packages.)
-LOCAL_MODULE_TAGS := eng
+updater_src_files := \
+ install.cpp \
+ blockimg.cpp \
+ updater.cpp
LOCAL_CLANG := true
-
LOCAL_SRC_FILES := $(updater_src_files)
-LOCAL_STATIC_LIBRARIES += libfec libfec_rs libext4_utils_static libsquashfs_utils libcrypto_static
+LOCAL_STATIC_LIBRARIES += \
+ $(TARGET_RECOVERY_UPDATER_LIBS) \
+ $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS) \
+ libfec \
+ libfec_rs \
+ libext4_utils_static \
+ libsquashfs_utils \
+ libcrypto_static \
+ libapplypatch \
+ libbase \
+ libotafault \
+ libedify \
+ libmtdutils \
+ libminzip \
+ libz \
+ libbz \
+ libcutils \
+ liblog \
+ libselinux
+
+tune2fs_static_libraries := \
+ libext2_com_err \
+ libext2_blkid \
+ libext2_quota \
+ libext2_uuid_static \
+ libext2_e2p \
+ libext2fs
+
+LOCAL_STATIC_LIBRARIES += \
+ libtune2fs \
+ $(tune2fs_static_libraries)
ifeq ($(TARGET_USERIMAGES_USE_EXT4), true)
LOCAL_CFLAGS += -DUSE_EXT4
@@ -44,20 +68,6 @@
libz
endif
-LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UPDATER_LIBS) $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS)
-LOCAL_STATIC_LIBRARIES += libapplypatch libbase libotafault libedify libmtdutils libminzip libz
-LOCAL_STATIC_LIBRARIES += libbz
-LOCAL_STATIC_LIBRARIES += libcutils liblog libc
-LOCAL_STATIC_LIBRARIES += libselinux
-tune2fs_static_libraries := \
- libext2_com_err \
- libext2_blkid \
- libext2_quota \
- libext2_uuid_static \
- libext2_e2p \
- libext2fs
-LOCAL_STATIC_LIBRARIES += libtune2fs $(tune2fs_static_libraries)
-
LOCAL_C_INCLUDES += external/e2fsprogs/misc
LOCAL_C_INCLUDES += $(LOCAL_PATH)/..
diff --git a/updater/blockimg.cpp b/updater/blockimg.cpp
index faa7008..56378d4 100644
--- a/updater/blockimg.cpp
+++ b/updater/blockimg.cpp
@@ -554,7 +554,7 @@
return -1;
}
- int fd = TEMP_FAILURE_RETRY(open(fn.c_str(), O_RDONLY));
+ int fd = TEMP_FAILURE_RETRY(ota_open(fn.c_str(), O_RDONLY));
unique_fd fd_holder(fd);
if (fd == -1) {
@@ -611,7 +611,7 @@
fprintf(stderr, " writing %d blocks to %s\n", blocks, cn.c_str());
- int fd = TEMP_FAILURE_RETRY(open(fn.c_str(), O_WRONLY | O_CREAT | O_TRUNC, STASH_FILE_MODE));
+ int fd = TEMP_FAILURE_RETRY(ota_open(fn.c_str(), O_WRONLY | O_CREAT | O_TRUNC, STASH_FILE_MODE));
unique_fd fd_holder(fd);
if (fd == -1) {
@@ -635,7 +635,7 @@
}
std::string dname = GetStashFileName(base, "", "");
- int dfd = TEMP_FAILURE_RETRY(open(dname.c_str(), O_RDONLY | O_DIRECTORY));
+ int dfd = TEMP_FAILURE_RETRY(ota_open(dname.c_str(), O_RDONLY | O_DIRECTORY));
unique_fd dfd_holder(dfd);
if (dfd == -1) {
@@ -1347,7 +1347,7 @@
return StringValue(strdup(""));
}
- params.fd = TEMP_FAILURE_RETRY(open(blockdev_filename->data, O_RDWR));
+ params.fd = TEMP_FAILURE_RETRY(ota_open(blockdev_filename->data, O_RDWR));
unique_fd fd_holder(params.fd);
if (params.fd == -1) {
@@ -1615,7 +1615,7 @@
return StringValue(strdup(""));
}
- int fd = open(blockdev_filename->data, O_RDWR);
+ int fd = ota_open(blockdev_filename->data, O_RDWR);
unique_fd fd_holder(fd);
if (fd < 0) {
ErrorAbort(state, "open \"%s\" failed: %s", blockdev_filename->data, strerror(errno));
@@ -1669,7 +1669,7 @@
return StringValue(strdup(""));
}
- int fd = open(arg_filename->data, O_RDONLY);
+ int fd = ota_open(arg_filename->data, O_RDONLY);
unique_fd fd_holder(fd);
if (fd == -1) {
ErrorAbort(state, "open \"%s\" failed: %s", arg_filename->data, strerror(errno));
diff --git a/updater/install.cpp b/updater/install.cpp
index 6ae1e5f..bc4cca9 100644
--- a/updater/install.cpp
+++ b/updater/install.cpp
@@ -996,7 +996,7 @@
}
FILE* f;
- f = fopen(filename, "rb");
+ f = ota_fopen(filename, "rb");
if (f == NULL) {
ErrorAbort(state, "%s: failed to open %s: %s", name, filename, strerror(errno));
goto done;
@@ -1005,12 +1005,12 @@
if (ota_fread(buffer, 1, st.st_size, f) != static_cast<size_t>(st.st_size)) {
ErrorAbort(state, "%s: failed to read %lld bytes from %s",
name, (long long)st.st_size+1, filename);
- fclose(f);
+ ota_fclose(f);
goto done;
}
buffer[st.st_size] = '\0';
- fclose(f);
+ ota_fclose(f);
char* line;
line = strtok(buffer, "\n");
@@ -1440,10 +1440,10 @@
// zero out the 'command' field of the bootloader message.
memset(buffer, 0, sizeof(((struct bootloader_message*)0)->command));
- FILE* f = fopen(filename, "r+b");
+ FILE* f = ota_fopen(filename, "r+b");
fseek(f, offsetof(struct bootloader_message, command), SEEK_SET);
ota_fwrite(buffer, sizeof(((struct bootloader_message*)0)->command), 1, f);
- fclose(f);
+ ota_fclose(f);
free(filename);
strcpy(buffer, "reboot,");
@@ -1482,7 +1482,7 @@
// bootloader message that the main recovery uses to save its
// arguments in case of the device restarting midway through
// package installation.
- FILE* f = fopen(filename, "r+b");
+ FILE* f = ota_fopen(filename, "r+b");
fseek(f, offsetof(struct bootloader_message, stage), SEEK_SET);
int to_write = strlen(stagestr)+1;
int max_size = sizeof(((struct bootloader_message*)0)->stage);
@@ -1491,7 +1491,7 @@
stagestr[max_size-1] = 0;
}
ota_fwrite(stagestr, to_write, 1, f);
- fclose(f);
+ ota_fclose(f);
free(stagestr);
return StringValue(filename);
@@ -1508,10 +1508,10 @@
if (ReadArgs(state, argv, 1, &filename) < 0) return NULL;
char buffer[sizeof(((struct bootloader_message*)0)->stage)];
- FILE* f = fopen(filename, "rb");
+ FILE* f = ota_fopen(filename, "rb");
fseek(f, offsetof(struct bootloader_message, stage), SEEK_SET);
ota_fread(buffer, sizeof(buffer), 1, f);
- fclose(f);
+ ota_fclose(f);
buffer[sizeof(buffer)-1] = '\0';
return StringValue(strdup(buffer));