Merge "Remove dumpkey build guards after completing code move." am: 5ffc038be6
am: ea0e0faae6

* commit 'ea0e0faae6c0e57deb1a53683b00ff4651a65502':
  Remove dumpkey build guards after completing code move.
diff --git a/minzip/SysUtil.c b/minzip/SysUtil.c
index 09ec876..e7dd17b 100644
--- a/minzip/SysUtil.c
+++ b/minzip/SysUtil.c
@@ -39,6 +39,11 @@
     pMap->length = sb.st_size;
     pMap->range_count = 1;
     pMap->ranges = malloc(sizeof(MappedRange));
+    if (pMap->ranges == NULL) {
+        LOGE("malloc failed: %s\n", strerror(errno));
+        munmap(memPtr, sb.st_size);
+        return false;
+    }
     pMap->ranges[0].addr = memPtr;
     pMap->ranges[0].length = sb.st_size;
 
@@ -50,7 +55,7 @@
     char block_dev[PATH_MAX+1];
     size_t size;
     unsigned int blksize;
-    unsigned int blocks;
+    size_t blocks;
     unsigned int range_count;
     unsigned int i;
 
@@ -69,49 +74,80 @@
         LOGE("failed to parse block map header\n");
         return -1;
     }
-
-    blocks = ((size-1) / blksize) + 1;
+    if (blksize != 0) {
+        blocks = ((size-1) / blksize) + 1;
+    }
+    if (size == 0 || blksize == 0 || blocks > SIZE_MAX / blksize || range_count == 0) {
+        LOGE("invalid data in block map file: size %zu, blksize %u, range_count %u\n",
+             size, blksize, range_count);
+        return -1;
+    }
 
     pMap->range_count = range_count;
-    pMap->ranges = malloc(range_count * sizeof(MappedRange));
-    memset(pMap->ranges, 0, range_count * sizeof(MappedRange));
+    pMap->ranges = calloc(range_count, sizeof(MappedRange));
+    if (pMap->ranges == NULL) {
+        LOGE("calloc(%u, %zu) failed: %s\n", range_count, sizeof(MappedRange), strerror(errno));
+        return -1;
+    }
 
     // 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) {
         LOGE("failed to reserve address space: %s\n", strerror(errno));
+        free(pMap->ranges);
         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) {
         LOGE("failed to open block device %s: %s\n", block_dev, strerror(errno));
+        munmap(reserve, blocks * blksize);
+        free(pMap->ranges);
         return -1;
     }
 
     unsigned char* next = reserve;
+    size_t remaining_size = blocks * blksize;
+    bool success = true;
     for (i = 0; i < range_count; ++i) {
-        int start, end;
-        if (fscanf(mapf, "%d %d\n", &start, &end) != 2) {
+        size_t start, end;
+        if (fscanf(mapf, "%zu %zu\n", &start, &end) != 2) {
             LOGE("failed to parse range %d in block map\n", i);
-            return -1;
+            success = false;
+            break;
+        }
+        size_t length = (end - start) * blksize;
+        if (end <= start || (end - start) > SIZE_MAX / blksize || length > remaining_size) {
+          LOGE("unexpected range in block map: %zu %zu\n", start, end);
+          success = false;
+          break;
         }
 
-        void* addr = mmap64(next, (end-start)*blksize, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, ((off64_t)start)*blksize);
+        void* addr = mmap64(next, length, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, ((off64_t)start)*blksize);
         if (addr == MAP_FAILED) {
             LOGE("failed to map block %d: %s\n", i, strerror(errno));
-            return -1;
+            success = false;
+            break;
         }
         pMap->ranges[i].addr = addr;
-        pMap->ranges[i].length = (end-start)*blksize;
+        pMap->ranges[i].length = length;
 
-        next += pMap->ranges[i].length;
+        next += length;
+        remaining_size -= length;
+    }
+    if (success && remaining_size != 0) {
+      LOGE("ranges in block map are invalid: remaining_size = %zu\n", remaining_size);
+      success = false;
+    }
+    if (!success) {
+      close(fd);
+      munmap(reserve, blocks * blksize);
+      free(pMap->ranges);
+      return -1;
     }
 
+    close(fd);
     pMap->addr = reserve;
     pMap->length = size;
 
@@ -134,6 +170,7 @@
 
         if (sysMapBlockFile(mapf, pMap) != 0) {
             LOGE("Map of '%s' failed\n", fn);
+            fclose(mapf);
             return -1;
         }
 
diff --git a/recovery.cpp b/recovery.cpp
index 3ce2185..4ae685f 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -79,7 +79,10 @@
 static const char *LOG_FILE = "/cache/recovery/log";
 static const char *LAST_INSTALL_FILE = "/cache/recovery/last_install";
 static const char *LOCALE_FILE = "/cache/recovery/last_locale";
+static const char *CONVERT_FBE_DIR = "/tmp/convert_fbe";
+static const char *CONVERT_FBE_FILE = "/tmp/convert_fbe/convert_fbe";
 static const char *CACHE_ROOT = "/cache";
+static const char *DATA_ROOT = "/data";
 static const char *SDCARD_ROOT = "/sdcard";
 static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log";
 static const char *TEMPORARY_INSTALL_FILE = "/tmp/last_install";
@@ -512,6 +515,7 @@
 
 static bool erase_volume(const char* volume) {
     bool is_cache = (strcmp(volume, CACHE_ROOT) == 0);
+    bool is_data = (strcmp(volume, DATA_ROOT) == 0);
 
     ui->SetBackground(RecoveryUI::ERASING);
     ui->SetProgressType(RecoveryUI::INDETERMINATE);
@@ -566,7 +570,28 @@
     ui->Print("Formatting %s...\n", volume);
 
     ensure_path_unmounted(volume);
-    int result = format_volume(volume);
+
+    int result;
+
+    if (is_data && reason && strcmp(reason, "convert_fbe") == 0) {
+        // Create convert_fbe breadcrumb file to signal to init
+        // to convert to file based encryption, not full disk encryption
+        if (mkdir(CONVERT_FBE_DIR, 0700) != 0) {
+            ui->Print("Failed to make convert_fbe dir %s\n", strerror(errno));
+            return true;
+        }
+        FILE* f = fopen(CONVERT_FBE_FILE, "wb");
+        if (!f) {
+            ui->Print("Failed to convert to file encryption %s\n", strerror(errno));
+            return true;
+        }
+        fclose(f);
+        result = format_volume(volume, CONVERT_FBE_DIR);
+        remove(CONVERT_FBE_FILE);
+        rmdir(CONVERT_FBE_DIR);
+    } else {
+        result = format_volume(volume);
+    }
 
     if (is_cache) {
         while (head) {
diff --git a/roots.cpp b/roots.cpp
index 12c6b5e..f361cb8 100644
--- a/roots.cpp
+++ b/roots.cpp
@@ -175,7 +175,7 @@
     return WEXITSTATUS(status);
 }
 
-int format_volume(const char* volume) {
+int format_volume(const char* volume, const char* directory) {
     Volume* v = volume_for_path(volume);
     if (v == NULL) {
         LOGE("unknown volume \"%s\"\n", volume);
@@ -241,7 +241,7 @@
         }
         int result;
         if (strcmp(v->fs_type, "ext4") == 0) {
-            result = make_ext4fs(v->blk_device, length, volume, sehandle);
+            result = make_ext4fs_directory(v->blk_device, length, volume, sehandle, directory);
         } else {   /* Has to be f2fs because we checked earlier. */
             if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0 && length < 0) {
                 LOGE("format_volume: crypt footer + negative length (%zd) not supported on %s\n", length, v->fs_type);
@@ -273,6 +273,10 @@
     return -1;
 }
 
+int format_volume(const char* volume) {
+    return format_volume(volume, NULL);
+}
+
 int setup_install_mounts() {
     if (fstab == NULL) {
         LOGE("can't set up install mounts: no fstab loaded\n");
diff --git a/roots.h b/roots.h
index 6e3b243..a14b7d9 100644
--- a/roots.h
+++ b/roots.h
@@ -41,6 +41,12 @@
 // it is mounted.
 int format_volume(const char* volume);
 
+// Reformat the given volume (must be the mount point only, eg
+// "/cache"), no paths permitted.  Attempts to unmount the volume if
+// it is mounted.
+// Copies 'directory' to root of the newly formatted volume
+int format_volume(const char* volume, const char* directory);
+
 // Ensure that all and only the volumes that packages expect to find
 // mounted (/tmp and /cache) are mounted.  Returns 0 on success.
 int setup_install_mounts();
diff --git a/uncrypt/uncrypt.cpp b/uncrypt/uncrypt.cpp
index 705744e..2a32108 100644
--- a/uncrypt/uncrypt.cpp
+++ b/uncrypt/uncrypt.cpp
@@ -406,15 +406,6 @@
     return 0;
 }
 
-static void reboot_to_recovery() {
-    ALOGI("rebooting to recovery");
-    property_set("sys.powerctl", "reboot,recovery");
-    while (true) {
-      pause();
-    }
-    ALOGE("reboot didn't succeed?");
-}
-
 static int uncrypt(const char* input_path, const char* map_file, int status_fd) {
 
     ALOGI("update package is \"%s\"", input_path);
@@ -543,7 +534,6 @@
 static void usage(const char* exename) {
     fprintf(stderr, "Usage of %s:\n", exename);
     fprintf(stderr, "%s [<package_path> <map_file>]  Uncrypt ota package.\n", exename);
-    fprintf(stderr, "%s --reboot  Clear BCB data and reboot to recovery.\n", exename);
     fprintf(stderr, "%s --clear-bcb  Clear BCB data in misc partition.\n", exename);
     fprintf(stderr, "%s --setup-bcb  Setup BCB data by command file.\n", exename);
     fprintf(stderr, "%s --read-bcb   Read BCB data from misc partition.\n", exename);
@@ -551,9 +541,7 @@
 
 int main(int argc, char** argv) {
     if (argc == 2) {
-        if (strcmp(argv[1], "--reboot") == 0) {
-            reboot_to_recovery();
-        } else if (strcmp(argv[1], "--clear-bcb") == 0) {
+        if (strcmp(argv[1], "--clear-bcb") == 0) {
             return clear_bcb(STATUS_FILE);
         } else if (strcmp(argv[1], "--setup-bcb") == 0) {
             return setup_bcb(COMMAND_FILE, STATUS_FILE);
diff --git a/uncrypt/uncrypt.rc b/uncrypt/uncrypt.rc
index b07c1da..d5d803b 100644
--- a/uncrypt/uncrypt.rc
+++ b/uncrypt/uncrypt.rc
@@ -3,11 +3,6 @@
     disabled
     oneshot
 
-service pre-recovery /system/bin/uncrypt --reboot
-    class main
-    disabled
-    oneshot
-
 service setup-bcb /system/bin/uncrypt --setup-bcb
     class main
     disabled
@@ -16,4 +11,4 @@
 service clear-bcb /system/bin/uncrypt --clear-bcb
     class main
     disabled
-    oneshot
\ No newline at end of file
+    oneshot
diff --git a/wear_ui.cpp b/wear_ui.cpp
index 50aeb38..8a57cff 100644
--- a/wear_ui.cpp
+++ b/wear_ui.cpp
@@ -36,6 +36,7 @@
 #include "ui.h"
 #include "cutils/properties.h"
 #include "android-base/strings.h"
+#include "android-base/stringprintf.h"
 
 static int char_width;
 static int char_height;
@@ -653,3 +654,35 @@
     }
     pthread_mutex_unlock(&updateMutex);
 }
+
+void WearRecoveryUI::PrintOnScreenOnly(const char *fmt, ...) {
+    va_list ap;
+    va_start(ap, fmt);
+    PrintV(fmt, false, ap);
+    va_end(ap);
+}
+
+void WearRecoveryUI::PrintV(const char* fmt, bool copy_to_stdout, va_list ap) {
+    std::string str;
+    android::base::StringAppendV(&str, fmt, ap);
+
+    if (copy_to_stdout) {
+        fputs(str.c_str(), stdout);
+    }
+
+    pthread_mutex_lock(&updateMutex);
+    if (text_rows > 0 && text_cols > 0) {
+        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;
+                text_row = (text_row + 1) % text_rows;
+                if (text_row == text_top) text_top = (text_top + 1) % text_rows;
+            }
+            if (*ptr != '\n') text[text_row][text_col++] = *ptr;
+        }
+        text[text_row][text_col] = '\0';
+        update_screen_locked();
+    }
+    pthread_mutex_unlock(&updateMutex);
+}
diff --git a/wear_ui.h b/wear_ui.h
index 63c1b6e..768141c 100644
--- a/wear_ui.h
+++ b/wear_ui.h
@@ -47,6 +47,7 @@
 
     // printing messages
     void Print(const char* fmt, ...);
+    void PrintOnScreenOnly(const char* fmt, ...) __printflike(2, 3);
     void ShowFile(const char* filename);
     void ShowFile(FILE* fp);
 
@@ -133,6 +134,7 @@
     void ClearText();
     void DrawTextLine(int x, int* y, const char* line, bool bold);
     void DrawTextLines(int x, int* y, const char* const* lines);
+    void PrintV(const char*, bool, va_list);
 };
 
 #endif  // RECOVERY_WEAR_UI_H