am d6b2b65d: Merge "Change init sequence to support file level encryption" into mnc-dev

* commit 'd6b2b65dc40c5af7feecf634b8ae55bf14fe8e6c':
  Change init sequence to support file level encryption
diff --git a/Android.mk b/Android.mk
index 0484065..cfe3030 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,11 +14,10 @@
 
 LOCAL_PATH := $(call my-dir)
 
-
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := fuse_sideload.c
-
+LOCAL_CLANG := true
 LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter
 LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
 
@@ -54,6 +53,7 @@
 RECOVERY_FSTAB_VERSION := 2
 LOCAL_CFLAGS += -DRECOVERY_API_VERSION=$(RECOVERY_API_VERSION)
 LOCAL_CFLAGS += -Wno-unused-parameter
+LOCAL_CLANG := true
 
 LOCAL_C_INCLUDES += \
     system/vold \
@@ -76,7 +76,6 @@
     libcutils \
     liblog \
     libselinux \
-    libstdc++ \
     libm \
     libc
 
@@ -98,6 +97,7 @@
 
 # All the APIs for testing
 include $(CLEAR_VARS)
+LOCAL_CLANG := true
 LOCAL_MODULE := libverifier
 LOCAL_MODULE_TAGS := tests
 LOCAL_SRC_FILES := \
@@ -105,6 +105,7 @@
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
+LOCAL_CLANG := true
 LOCAL_MODULE := verifier_test
 LOCAL_FORCE_STATIC_EXECUTABLE := true
 LOCAL_MODULE_TAGS := tests
@@ -119,7 +120,6 @@
     libminui \
     libminzip \
     libcutils \
-    libstdc++ \
     libc
 include $(BUILD_EXECUTABLE)
 
diff --git a/adb_install.cpp b/adb_install.cpp
index e3b94ea..4cfcb2a 100644
--- a/adb_install.cpp
+++ b/adb_install.cpp
@@ -91,7 +91,7 @@
     // FUSE_SIDELOAD_HOST_PATHNAME will start to exist once the host
     // connects and starts serving a package.  Poll for its
     // appearance.  (Note that inotify doesn't work with FUSE.)
-    int result;
+    int result = INSTALL_ERROR;
     int status;
     bool waited = false;
     struct stat st;
diff --git a/applypatch/Android.mk b/applypatch/Android.mk
index 4984093..eb3e458 100644
--- a/applypatch/Android.mk
+++ b/applypatch/Android.mk
@@ -13,8 +13,10 @@
 # limitations under the License.
 
 LOCAL_PATH := $(call my-dir)
+
 include $(CLEAR_VARS)
 
+LOCAL_CLANG := true
 LOCAL_SRC_FILES := applypatch.c bspatch.c freecache.c imgpatch.c utils.c
 LOCAL_MODULE := libapplypatch
 LOCAL_MODULE_TAGS := eng
@@ -25,28 +27,31 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_CLANG := true
 LOCAL_SRC_FILES := main.c
 LOCAL_MODULE := applypatch
 LOCAL_C_INCLUDES += bootable/recovery
 LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz
-LOCAL_SHARED_LIBRARIES += libz libcutils libstdc++ libc
+LOCAL_SHARED_LIBRARIES += libz libcutils libc
 
 include $(BUILD_EXECUTABLE)
 
 include $(CLEAR_VARS)
 
+LOCAL_CLANG := true
 LOCAL_SRC_FILES := main.c
 LOCAL_MODULE := applypatch_static
 LOCAL_FORCE_STATIC_EXECUTABLE := true
 LOCAL_MODULE_TAGS := eng
 LOCAL_C_INCLUDES += bootable/recovery
 LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz
-LOCAL_STATIC_LIBRARIES += libz libcutils libstdc++ libc
+LOCAL_STATIC_LIBRARIES += libz libcutils libc
 
 include $(BUILD_EXECUTABLE)
 
 include $(CLEAR_VARS)
 
+LOCAL_CLANG := true
 LOCAL_SRC_FILES := imgdiff.c utils.c bsdiff.c
 LOCAL_MODULE := imgdiff
 LOCAL_FORCE_STATIC_EXECUTABLE := true
diff --git a/edify/Android.mk b/edify/Android.mk
index 03c04e4..c366450 100644
--- a/edify/Android.mk
+++ b/edify/Android.mk
@@ -25,6 +25,7 @@
 LOCAL_MODULE := edify
 LOCAL_YACCFLAGS := -v
 LOCAL_CFLAGS += -Wno-unused-parameter
+LOCAL_CLANG := true
 
 include $(BUILD_HOST_EXECUTABLE)
 
@@ -38,5 +39,6 @@
 LOCAL_CFLAGS := $(edify_cflags)
 LOCAL_CFLAGS += -Wno-unused-parameter
 LOCAL_MODULE := libedify
+LOCAL_CLANG := true
 
 include $(BUILD_STATIC_LIBRARY)
diff --git a/etc/init.rc b/etc/init.rc
index 4277277..dc18659 100644
--- a/etc/init.rc
+++ b/etc/init.rc
@@ -5,7 +5,6 @@
     start healthd
 
 on init
-    export PATH /sbin:/system/bin
     export ANDROID_ROOT /system
     export ANDROID_DATA /data
     export EXTERNAL_STORAGE /sdcard
diff --git a/install.cpp b/install.cpp
index c7d382f..7d88ed7 100644
--- a/install.cpp
+++ b/install.cpp
@@ -164,9 +164,9 @@
         } else if (strcmp(command, "ui_print") == 0) {
             char* str = strtok(NULL, "\n");
             if (str) {
-                ui->Print("%s", str);
+                ui->PrintOnScreenOnly("%s", str);
             } else {
-                ui->Print("\n");
+                ui->PrintOnScreenOnly("\n");
             }
             fflush(stdout);
         } else if (strcmp(command, "wipe_cache") == 0) {
diff --git a/minadbd/Android.mk b/minadbd/Android.mk
index a7a3e08..3db3b41 100644
--- a/minadbd/Android.mk
+++ b/minadbd/Android.mk
@@ -15,6 +15,7 @@
     fuse_adb_provider.cpp \
     services.cpp \
 
+LOCAL_CLANG := true
 LOCAL_MODULE := libminadbd
 LOCAL_CFLAGS := $(minadbd_cflags)
 LOCAL_CONLY_FLAGS := -Wimplicit-function-declaration
diff --git a/minadbd/adb_main.cpp b/minadbd/adb_main.cpp
index 7fae99a..724f39c 100644
--- a/minadbd/adb_main.cpp
+++ b/minadbd/adb_main.cpp
@@ -27,13 +27,9 @@
 #include "adb_auth.h"
 #include "transport.h"
 
-int adb_main(int is_daemon, int server_port)
-{
-    atexit(usb_cleanup);
-
+int adb_main(int is_daemon, int server_port) {
     adb_device_banner = "sideload";
 
-    // No SIGCHLD. Let the service subproc handle its children.
     signal(SIGPIPE, SIG_IGN);
 
     // We can't require authentication for sideloading. http://b/22025550.
diff --git a/minadbd/services.cpp b/minadbd/services.cpp
index dd1fd7c..859463c 100644
--- a/minadbd/services.cpp
+++ b/minadbd/services.cpp
@@ -61,8 +61,7 @@
     exit(result == 0 ? 0 : 1);
 }
 
-static int create_service_thread(void (*func)(int, void *), void *cookie)
-{
+static int create_service_thread(void (*func)(int, void *), void *cookie) {
     int s[2];
     if(adb_socketpair(s)) {
         printf("cannot create service socket pair\n");
@@ -75,8 +74,7 @@
     sti->cookie = cookie;
     sti->fd = s[1];
 
-    adb_thread_t t;
-    if (adb_thread_create( &t, service_bootstrap_func, sti)){
+    if (!adb_thread_create(service_bootstrap_func, sti)) {
         free(sti);
         adb_close(s[0]);
         adb_close(s[1]);
diff --git a/minui/Android.mk b/minui/Android.mk
index 97724fb..3057f45 100644
--- a/minui/Android.mk
+++ b/minui/Android.mk
@@ -41,6 +41,7 @@
 
 # Used by OEMs for factory test images.
 include $(CLEAR_VARS)
+LOCAL_CLANG := true
 LOCAL_MODULE := libminui
 LOCAL_WHOLE_STATIC_LIBRARIES += libminui
 LOCAL_SHARED_LIBRARIES := libpng
diff --git a/minzip/Android.mk b/minzip/Android.mk
index 045f355..22eabfb 100644
--- a/minzip/Android.mk
+++ b/minzip/Android.mk
@@ -16,6 +16,8 @@
 
 LOCAL_MODULE := libminzip
 
-LOCAL_CFLAGS += -Wall
+LOCAL_CLANG := true
+
+LOCAL_CFLAGS += -Werror -Wall
 
 include $(BUILD_STATIC_LIBRARY)
diff --git a/minzip/SysUtil.c b/minzip/SysUtil.c
index b160c9e..3dd3572 100644
--- a/minzip/SysUtil.c
+++ b/minzip/SysUtil.c
@@ -3,86 +3,46 @@
  *
  * System utilities.
  */
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <assert.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
-#include <errno.h>
-#include <assert.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 #define LOG_TAG "sysutil"
 #include "Log.h"
 #include "SysUtil.h"
 
-static int getFileStartAndLength(int fd, off_t *start_, size_t *length_)
-{
-    off_t start, end;
-    size_t length;
-
-    assert(start_ != NULL);
-    assert(length_ != NULL);
-
-    // TODO: isn't start always 0 for the single call site? just use fstat instead?
-
-    start = TEMP_FAILURE_RETRY(lseek(fd, 0L, SEEK_CUR));
-    end = TEMP_FAILURE_RETRY(lseek(fd, 0L, SEEK_END));
-
-    if (TEMP_FAILURE_RETRY(lseek(fd, start, SEEK_SET)) == -1 ||
-                start == (off_t) -1 || end == (off_t) -1) {
-        LOGE("could not determine length of file\n");
-        return -1;
-    }
-
-    length = end - start;
-    if (length == 0) {
-        LOGE("file is empty\n");
-        return -1;
-    }
-
-    *start_ = start;
-    *length_ = length;
-
-    return 0;
-}
-
-/*
- * 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".
- */
-static int sysMapFD(int fd, MemMapping* pMap)
-{
-    off_t start;
-    size_t length;
-    void* memPtr;
-
+static bool sysMapFD(int fd, MemMapping* pMap) {
     assert(pMap != NULL);
 
-    if (getFileStartAndLength(fd, &start, &length) < 0)
-        return -1;
+    struct stat sb;
+    if (fstat(fd, &sb) == -1) {
+        LOGW("fstat(%d) failed: %s\n", fd, strerror(errno));
+        return false;
+    }
 
-    memPtr = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, start);
+    void* memPtr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
     if (memPtr == MAP_FAILED) {
-        LOGW("mmap(%d, R, PRIVATE, %d, %d) failed: %s\n", (int) length,
-            fd, (int) start, strerror(errno));
-        return -1;
+        LOGW("mmap(%d, R, PRIVATE, %d, 0) failed: %s\n", (int) sb.st_size, fd, strerror(errno));
+        return false;
     }
 
     pMap->addr = memPtr;
-    pMap->length = length;
+    pMap->length = sb.st_size;
     pMap->range_count = 1;
     pMap->ranges = malloc(sizeof(MappedRange));
     pMap->ranges[0].addr = memPtr;
-    pMap->ranges[0].length = length;
+    pMap->ranges[0].length = sb.st_size;
 
-    return 0;
+    return true;
 }
 
 static int sysMapBlockFile(FILE* mapf, MemMapping* pMap)
@@ -180,13 +140,13 @@
         fclose(mapf);
     } else {
         // This is a regular file.
-        int fd = open(fn, O_RDONLY, 0);
-        if (fd < 0) {
+        int fd = open(fn, O_RDONLY);
+        if (fd == -1) {
             LOGE("Unable to open '%s': %s\n", fn, strerror(errno));
             return -1;
         }
 
-        if (sysMapFD(fd, pMap) != 0) {
+        if (!sysMapFD(fd, pMap)) {
             LOGE("Map of '%s' failed\n", fn);
             close(fd);
             return -1;
diff --git a/minzip/Zip.c b/minzip/Zip.c
index 40712e0..c1dec74 100644
--- a/minzip/Zip.c
+++ b/minzip/Zip.c
@@ -506,7 +506,6 @@
     void *cookie)
 {
     long result = -1;
-    unsigned char readBuf[32 * 1024];
     unsigned char procBuf[32 * 1024];
     z_stream zstream;
     int zerr;
@@ -603,7 +602,6 @@
     void *cookie)
 {
     bool ret = false;
-    off_t oldOff;
 
     switch (pEntry->compression) {
     case STORED:
@@ -621,13 +619,6 @@
     return ret;
 }
 
-static bool crcProcessFunction(const unsigned char *data, int dataLen,
-        void *crc)
-{
-    *(unsigned long *)crc = crc32(*(unsigned long *)crc, data, dataLen);
-    return true;
-}
-
 typedef struct {
     char *buf;
     int bufLen;
diff --git a/mtdutils/Android.mk b/mtdutils/Android.mk
index f04355b..b7d35c2 100644
--- a/mtdutils/Android.mk
+++ b/mtdutils/Android.mk
@@ -6,10 +6,12 @@
 	mounts.c
 
 LOCAL_MODULE := libmtdutils
+LOCAL_CLANG := true
 
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
+LOCAL_CLANG := true
 LOCAL_SRC_FILES := flash_image.c
 LOCAL_MODULE := flash_image
 LOCAL_MODULE_TAGS := eng
diff --git a/recovery.cpp b/recovery.cpp
index b7a5458..83ca581 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -31,24 +31,24 @@
 #include <time.h>
 #include <unistd.h>
 
+#include <adb.h>
 #include <base/file.h>
 #include <base/stringprintf.h>
+#include <cutils/android_reboot.h>
+#include <cutils/properties.h>
 
+#include "adb_install.h"
 #include "bootloader.h"
 #include "common.h"
-#include "cutils/properties.h"
-#include "cutils/android_reboot.h"
+#include "device.h"
+#include "fuse_sdcard_provider.h"
+#include "fuse_sideload.h"
 #include "install.h"
 #include "minui/minui.h"
 #include "minzip/DirUtil.h"
 #include "roots.h"
 #include "ui.h"
 #include "screen_ui.h"
-#include "device.h"
-#include "adb_install.h"
-#include "adb.h"
-#include "fuse_sideload.h"
-#include "fuse_sdcard_provider.h"
 
 struct selabel_handle *sehandle;
 
@@ -326,14 +326,18 @@
     ensure_path_mounted(LAST_KMSG_FILE);
 
     for (int i = max-1; i >= 0; --i) {
-        std::string old_log = android::base::StringPrintf((i == 0) ? "%s" : "%s.%d",
-                LAST_LOG_FILE, i);
+        std::string old_log = android::base::StringPrintf("%s", LAST_LOG_FILE);
+        if (i > 0) {
+          old_log += "." + std::to_string(i);
+        }
         std::string new_log = android::base::StringPrintf("%s.%d", LAST_LOG_FILE, i+1);
         // Ignore errors if old_log doesn't exist.
         rename(old_log.c_str(), new_log.c_str());
 
-        std::string old_kmsg = android::base::StringPrintf((i == 0) ? "%s" : "%s.%d",
-                LAST_KMSG_FILE, i);
+        std::string old_kmsg = android::base::StringPrintf("%s", LAST_KMSG_FILE);
+        if (i > 0) {
+          old_kmsg += "." + std::to_string(i);
+        }
         std::string new_kmsg = android::base::StringPrintf("%s.%d", LAST_KMSG_FILE, i+1);
         rename(old_kmsg.c_str(), new_kmsg.c_str());
     }
@@ -706,7 +710,10 @@
     // Add LAST_KMSG_FILE + LAST_KMSG_FILE.x
     for (int i = 0; i < KEEP_LOG_COUNT; i++) {
         char* log_file;
-        if (asprintf(&log_file, (i == 0) ? "%s" : "%s.%d", LAST_LOG_FILE, i) == -1) {
+        int ret;
+        ret = (i == 0) ? asprintf(&log_file, "%s", LAST_LOG_FILE) :
+                asprintf(&log_file, "%s.%d", LAST_LOG_FILE, i);
+        if (ret == -1) {
             // memory allocation failure - return early. Should never happen.
             return;
         }
@@ -717,7 +724,9 @@
         }
 
         char* kmsg_file;
-        if (asprintf(&kmsg_file, (i == 0) ? "%s" : "%s.%d", LAST_KMSG_FILE, i) == -1) {
+        ret = (i == 0) ? asprintf(&kmsg_file, "%s", LAST_KMSG_FILE) :
+                asprintf(&kmsg_file, "%s.%d", LAST_KMSG_FILE, i);
+        if (ret == -1) {
             // memory allocation failure - return early. Should never happen.
             return;
         }
@@ -758,6 +767,7 @@
     char* path = browse_directory(SDCARD_ROOT, device);
     if (path == NULL) {
         ui->Print("\n-- No package file selected.\n");
+        ensure_path_unmounted(SDCARD_ROOT);
         return INSTALL_ERROR;
     }
 
@@ -1114,6 +1124,9 @@
             property_set(ANDROID_RB_PROPERTY, "reboot,");
             break;
     }
-    sleep(5); // should reboot before this finishes
+    while (true) {
+      pause();
+    }
+    // Should be unreachable.
     return EXIT_SUCCESS;
 }
diff --git a/res-560dpi b/res-560dpi
new file mode 120000
index 0000000..8576a9b
--- /dev/null
+++ b/res-560dpi
@@ -0,0 +1 @@
+res-xxhdpi
\ No newline at end of file
diff --git a/screen_ui.cpp b/screen_ui.cpp
index ff95915..ddf85c1 100644
--- a/screen_ui.cpp
+++ b/screen_ui.cpp
@@ -30,8 +30,10 @@
 
 #include <vector>
 
-#include "base/strings.h"
-#include "cutils/properties.h"
+#include <base/strings.h>
+#include <base/stringprintf.h>
+#include <cutils/properties.h>
+
 #include "common.h"
 #include "device.h"
 #include "minui/minui.h"
@@ -506,18 +508,17 @@
     pthread_mutex_unlock(&updateMutex);
 }
 
-void ScreenRecoveryUI::Print(const char *fmt, ...) {
-    char buf[256];
-    va_list ap;
-    va_start(ap, fmt);
-    vsnprintf(buf, 256, fmt, ap);
-    va_end(ap);
+void ScreenRecoveryUI::PrintV(const char* fmt, bool copy_to_stdout, va_list ap) {
+    std::string str;
+    android::base::StringAppendV(&str, fmt, ap);
 
-    fputs(buf, stdout);
+    if (copy_to_stdout) {
+        fputs(str.c_str(), stdout);
+    }
 
     pthread_mutex_lock(&updateMutex);
     if (text_rows_ > 0 && text_cols_ > 0) {
-        for (const char* ptr = buf; *ptr != '\0'; ++ptr) {
+        for (const char* ptr = str.c_str(); *ptr != '\0'; ++ptr) {
             if (*ptr == '\n' || text_col_ >= text_cols_) {
                 text_[text_row_][text_col_] = '\0';
                 text_col_ = 0;
@@ -532,6 +533,20 @@
     pthread_mutex_unlock(&updateMutex);
 }
 
+void ScreenRecoveryUI::Print(const char* fmt, ...) {
+    va_list ap;
+    va_start(ap, fmt);
+    PrintV(fmt, true, ap);
+    va_end(ap);
+}
+
+void ScreenRecoveryUI::PrintOnScreenOnly(const char *fmt, ...) {
+    va_list ap;
+    va_start(ap, fmt);
+    PrintV(fmt, false, ap);
+    va_end(ap);
+}
+
 void ScreenRecoveryUI::PutChar(char ch) {
     pthread_mutex_lock(&updateMutex);
     if (ch != '\n') text_[text_row_][text_col_++] = ch;
diff --git a/screen_ui.h b/screen_ui.h
index ea05bf1..8e18864 100644
--- a/screen_ui.h
+++ b/screen_ui.h
@@ -49,6 +49,7 @@
 
     // printing messages
     void Print(const char* fmt, ...) __printflike(2, 3);
+    void PrintOnScreenOnly(const char* fmt, ...) __printflike(2, 3);
     void ShowFile(const char* filename);
 
     // menu display
@@ -125,6 +126,7 @@
     void ProgressThreadLoop();
 
     void ShowFile(FILE*);
+    void PrintV(const char*, bool, va_list);
     void PutChar(char);
     void ClearText();
 
diff --git a/tests/Android.mk b/tests/Android.mk
index 02a272a..4ce00b4 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -17,6 +17,7 @@
 LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
+LOCAL_CLANG := true
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 LOCAL_STATIC_LIBRARIES := libverifier
 LOCAL_SRC_FILES := asn1_decoder_test.cpp
diff --git a/ui.cpp b/ui.cpp
index 1a0b079..2efb759 100644
--- a/ui.cpp
+++ b/ui.cpp
@@ -28,6 +28,7 @@
 #include <time.h>
 #include <unistd.h>
 
+#include <cutils/properties.h>
 #include <cutils/android_reboot.h>
 
 #include "common.h"
@@ -174,7 +175,8 @@
 
           case RecoveryUI::REBOOT:
             if (reboot_enabled) {
-                android_reboot(ANDROID_RB_RESTART, 0, 0);
+                property_set(ANDROID_RB_PROPERTY, "reboot,");
+                while (true) { pause(); }
             }
             break;
 
diff --git a/ui.h b/ui.h
index 4dcaa0f..ca72911 100644
--- a/ui.h
+++ b/ui.h
@@ -62,8 +62,10 @@
     virtual bool WasTextEverVisible() = 0;
 
     // Write a message to the on-screen log (shown if the user has
-    // toggled on the text display).
+    // toggled on the text display). Print() will also dump the message
+    // to stdout / log file, while PrintOnScreenOnly() not.
     virtual void Print(const char* fmt, ...) __printflike(2, 3) = 0;
+    virtual void PrintOnScreenOnly(const char* fmt, ...) __printflike(2, 3) = 0;
 
     virtual void ShowFile(const char* filename) = 0;
 
diff --git a/uncrypt/Android.mk b/uncrypt/Android.mk
index c7d4d37..e73c8f1 100644
--- a/uncrypt/Android.mk
+++ b/uncrypt/Android.mk
@@ -16,6 +16,8 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_CLANG := true
+
 LOCAL_SRC_FILES := uncrypt.cpp
 
 LOCAL_MODULE := uncrypt
diff --git a/uncrypt/uncrypt.cpp b/uncrypt/uncrypt.cpp
index 1db3013..20a2729 100644
--- a/uncrypt/uncrypt.cpp
+++ b/uncrypt/uncrypt.cpp
@@ -53,8 +53,10 @@
 
 #include <base/file.h>
 #include <base/strings.h>
+#include <cutils/android_reboot.h>
 #include <cutils/properties.h>
 #include <fs_mgr.h>
+
 #define LOG_TAG "uncrypt"
 #include <log/log.h>
 
@@ -358,7 +360,9 @@
 static void reboot_to_recovery() {
     ALOGI("rebooting to recovery");
     property_set("sys.powerctl", "reboot,recovery");
-    sleep(10);
+    while (true) {
+      pause();
+    }
     ALOGE("reboot didn't succeed?");
 }
 
diff --git a/updater/Android.mk b/updater/Android.mk
index ff02a33..a0ea06f 100644
--- a/updater/Android.mk
+++ b/updater/Android.mk
@@ -17,6 +17,8 @@
 # needed only for OTA packages.)
 LOCAL_MODULE_TAGS := eng
 
+LOCAL_CLANG := true
+
 LOCAL_SRC_FILES := $(updater_src_files)
 
 ifeq ($(TARGET_USERIMAGES_USE_EXT4), true)
@@ -32,7 +34,7 @@
 LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UPDATER_LIBS) $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS)
 LOCAL_STATIC_LIBRARIES += libapplypatch libedify libmtdutils libminzip libz
 LOCAL_STATIC_LIBRARIES += libmincrypt libbz
-LOCAL_STATIC_LIBRARIES += libcutils liblog libstdc++ libc
+LOCAL_STATIC_LIBRARIES += libcutils liblog libc
 LOCAL_STATIC_LIBRARIES += libselinux
 tune2fs_static_libraries := \
  libext2_com_err \
diff --git a/updater/blockimg.c b/updater/blockimg.c
index 5b8a6a3..a6a3895 100644
--- a/updater/blockimg.c
+++ b/updater/blockimg.c
@@ -60,30 +60,91 @@
     int pos[0];
 } RangeSet;
 
+#define RANGESET_MAX_POINTS \
+    ((int)((INT_MAX / sizeof(int)) - sizeof(RangeSet)))
+
 static RangeSet* parse_range(char* text) {
     char* save;
-    int num;
-    num = strtol(strtok_r(text, ",", &save), NULL, 0);
+    char* token;
+    int i, num;
+    long int val;
+    RangeSet* out = NULL;
+    size_t bufsize;
 
-    RangeSet* out = malloc(sizeof(RangeSet) + num * sizeof(int));
-    if (out == NULL) {
-        fprintf(stderr, "failed to allocate range of %zu bytes\n",
-                sizeof(RangeSet) + num * sizeof(int));
-        exit(1);
+    if (!text) {
+        goto err;
     }
+
+    token = strtok_r(text, ",", &save);
+
+    if (!token) {
+        goto err;
+    }
+
+    val = strtol(token, NULL, 0);
+
+    if (val < 2 || val > RANGESET_MAX_POINTS) {
+        goto err;
+    } else if (val % 2) {
+        goto err; // must be even
+    }
+
+    num = (int) val;
+    bufsize = sizeof(RangeSet) + num * sizeof(int);
+
+    out = malloc(bufsize);
+
+    if (!out) {
+        fprintf(stderr, "failed to allocate range of %zu bytes\n", bufsize);
+        goto err;
+    }
+
     out->count = num / 2;
     out->size = 0;
-    int i;
+
     for (i = 0; i < num; ++i) {
-        out->pos[i] = strtol(strtok_r(NULL, ",", &save), NULL, 0);
-        if (i%2) {
+        token = strtok_r(NULL, ",", &save);
+
+        if (!token) {
+            goto err;
+        }
+
+        val = strtol(token, NULL, 0);
+
+        if (val < 0 || val > INT_MAX) {
+            goto err;
+        }
+
+        out->pos[i] = (int) val;
+
+        if (i % 2) {
+            if (out->pos[i - 1] >= out->pos[i]) {
+                goto err; // empty or negative range
+            }
+
+            if (out->size > INT_MAX - out->pos[i]) {
+                goto err; // overflow
+            }
+
             out->size += out->pos[i];
         } else {
+            if (out->size < 0) {
+                goto err;
+            }
+
             out->size -= out->pos[i];
         }
     }
 
+    if (out->size <= 0) {
+        goto err;
+    }
+
     return out;
+
+err:
+    fprintf(stderr, "failed to parse range '%s'\n", text ? text : "NULL");
+    exit(1);
 }
 
 static int range_overlaps(RangeSet* r1, RangeSet* r2) {
diff --git a/updater/install.c b/updater/install.c
index 01a5dd2..4a0e064 100644
--- a/updater/install.c
+++ b/updater/install.c
@@ -61,6 +61,11 @@
         line = strtok(NULL, "\n");
     }
     fprintf(ui->cmd_pipe, "ui_print\n");
+
+    // The recovery will only print the contents to screen for pipe command
+    // ui_print. We need to dump the contents to stderr (which has been
+    // redirected to the log file) directly.
+    fprintf(stderr, "%s", buffer);
 }
 
 __attribute__((__format__(printf, 2, 3))) __nonnull((2))
diff --git a/verifier_test.cpp b/verifier_test.cpp
index 82546ed..21633dc 100644
--- a/verifier_test.cpp
+++ b/verifier_test.cpp
@@ -141,6 +141,12 @@
         vfprintf(stderr, fmt, ap);
         va_end(ap);
     }
+    void PrintOnScreenOnly(const char* fmt, ...) {
+        va_list ap;
+        va_start(ap, fmt);
+        vfprintf(stderr, fmt, ap);
+        va_end(ap);
+    }
     void ShowFile(const char*) { }
 
     void StartMenu(const char* const * headers, const char* const * items,