Fix integer overflow in utf{16,32}_to_utf8_length am: f0a43dede9 am: 33abf90994 am: 789673b15c am: 1436927851 am: d70e582d67
am: 62d5a78df3

Change-Id: If605b2b03790475250c3a5c9627b9f6177c01226
diff --git a/adb/adb.h b/adb/adb.h
index 971b8da..b1d9896 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -160,8 +160,10 @@
 int  init_socket_transport(atransport *t, int s, int port, int local);
 void init_usb_transport(atransport *t, usb_handle *usb, ConnectionState state);
 
+std::string getEmulatorSerialString(int console_port);
 #if ADB_HOST
 atransport* find_emulator_transport_by_adb_port(int adb_port);
+atransport* find_emulator_transport_by_console_port(int console_port);
 #endif
 
 int service_to_fd(const char* name, const atransport* transport);
diff --git a/adb/bugreport.cpp b/adb/bugreport.cpp
index 9ed44a7..c348dd5 100644
--- a/adb/bugreport.cpp
+++ b/adb/bugreport.cpp
@@ -47,7 +47,7 @@
           show_progress_(show_progress),
           status_(0),
           line_() {
-        SetLineMessage();
+        SetLineMessage("generating");
     }
 
     void OnStdout(const char* buffer, int length) {
@@ -97,6 +97,7 @@
                                                           OS_PATH_SEPARATOR, dest_file_.c_str());
             }
             std::vector<const char*> srcs{src_file_.c_str()};
+            SetLineMessage("pulling");
             status_ =
                 br_->DoSyncPull(srcs, destination.c_str(), true, line_message_.c_str()) ? 0 : 1;
             if (status_ != 0) {
@@ -111,9 +112,8 @@
     }
 
   private:
-    void SetLineMessage() {
-        line_message_ =
-            android::base::StringPrintf("generating %s", adb_basename(dest_file_).c_str());
+    void SetLineMessage(const std::string& action) {
+        line_message_ = action + " " + adb_basename(dest_file_);
     }
 
     void SetSrcFile(const std::string path) {
@@ -121,7 +121,7 @@
         if (!dest_dir_.empty()) {
             // Only uses device-provided name when user passed a directory.
             dest_file_ = adb_basename(path);
-            SetLineMessage();
+            SetLineMessage("generating");
         }
     }
 
diff --git a/adb/bugreport_test.cpp b/adb/bugreport_test.cpp
index 3cd2b6d..1129285 100644
--- a/adb/bugreport_test.cpp
+++ b/adb/bugreport_test.cpp
@@ -189,7 +189,7 @@
         .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
                         WithArg<4>(ReturnCallbackDone())));
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
-                                true, StrEq("generating da_bugreport.zip")))
+                                true, StrEq("pulling da_bugreport.zip")))
         .WillOnce(Return(true));
 
     const char* args[] = {"bugreport"};
@@ -209,7 +209,7 @@
                         WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip\n")),
                         WithArg<4>(ReturnCallbackDone())));
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
-                                true, StrEq("generating da_bugreport.zip")))
+                                true, StrEq("pulling da_bugreport.zip")))
         .WillOnce(Return(true));
 
     const char* args[] = {"bugreport"};
@@ -223,7 +223,7 @@
         .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
                         WithArg<4>(ReturnCallbackDone())));
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
-                                true, StrEq("generating file.zip")))
+                                true, StrEq("pulling file.zip")))
         .WillOnce(Return(true));
 
     const char* args[] = {"bugreport", "file.zip"};
@@ -239,7 +239,7 @@
                         WithArg<4>(WriteOnStdout("/bugreport.zip")),
                         WithArg<4>(ReturnCallbackDone())));
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
-                                true, StrEq("generating file.zip")))
+                                true, StrEq("pulling file.zip")))
         .WillOnce(Return(true));
 
     const char* args[] = {"bugreport", "file.zip"};
@@ -275,7 +275,7 @@
             WithArg<4>(ReturnCallbackDone())));
     // clang-format on
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
-                                true, StrEq("generating file.zip")))
+                                true, StrEq("pulling file.zip")))
         .WillOnce(Return(true));
 
     const char* args[] = {"bugreport", "file.zip"};
@@ -294,7 +294,7 @@
                         WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
                         WithArg<4>(ReturnCallbackDone())));
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
-                                true, StrEq("generating da_bugreport.zip")))
+                                true, StrEq("pulling da_bugreport.zip")))
         .WillOnce(Return(true));
 
     const char* args[] = {"bugreport", td.path};
@@ -308,7 +308,7 @@
         .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip\n")),
                         WithArg<4>(ReturnCallbackDone())));
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
-                                true, StrEq("generating file.zip")))
+                                true, StrEq("pulling file.zip")))
         .WillOnce(Return(true));
 
     const char* args[] = {"bugreport", "file"};
@@ -327,7 +327,7 @@
                         WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
                         WithArg<4>(ReturnCallbackDone())));
     EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
-                                true, StrEq("generating da_bugreport.zip")))
+                                true, StrEq("pulling da_bugreport.zip")))
         .WillOnce(Return(true));
 
     const char* args[] = {"bugreport", td.path};
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 23827de..51d828a 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -1430,6 +1430,16 @@
 #endif
 }
 
+static bool _use_legacy_install() {
+    FeatureSet features;
+    std::string error;
+    if (!adb_get_feature_set(&features, &error)) {
+        fprintf(stderr, "error: %s\n", error.c_str());
+        return true;
+    }
+    return !CanUseFeature(features, kFeatureCmd);
+}
+
 int adb_commandline(int argc, const char **argv) {
     int no_daemon = 0;
     int is_daemon = 0;
@@ -1797,17 +1807,10 @@
     }
     else if (!strcmp(argv[0], "install")) {
         if (argc < 2) return usage();
-        FeatureSet features;
-        std::string error;
-        if (!adb_get_feature_set(&features, &error)) {
-            fprintf(stderr, "error: %s\n", error.c_str());
-            return 1;
+        if (_use_legacy_install()) {
+            return install_app_legacy(transport_type, serial, argc, argv);
         }
-
-        if (CanUseFeature(features, kFeatureCmd)) {
-            return install_app(transport_type, serial, argc, argv);
-        }
-        return install_app_legacy(transport_type, serial, argc, argv);
+        return install_app(transport_type, serial, argc, argv);
     }
     else if (!strcmp(argv[0], "install-multiple")) {
         if (argc < 2) return usage();
@@ -1815,17 +1818,10 @@
     }
     else if (!strcmp(argv[0], "uninstall")) {
         if (argc < 2) return usage();
-        FeatureSet features;
-        std::string error;
-        if (!adb_get_feature_set(&features, &error)) {
-            fprintf(stderr, "error: %s\n", error.c_str());
-            return 1;
+        if (_use_legacy_install()) {
+            return uninstall_app_legacy(transport_type, serial, argc, argv);
         }
-
-        if (CanUseFeature(features, kFeatureCmd)) {
-            return uninstall_app(transport_type, serial, argc, argv);
-        }
-        return uninstall_app_legacy(transport_type, serial, argc, argv);
+        return uninstall_app(transport_type, serial, argc, argv);
     }
     else if (!strcmp(argv[0], "sync")) {
         std::string src;
@@ -2031,7 +2027,6 @@
     int i;
     struct stat sb;
     uint64_t total_size = 0;
-
     // Find all APK arguments starting at end.
     // All other arguments passed through verbatim.
     int first_apk = -1;
@@ -2056,7 +2051,14 @@
         return 1;
     }
 
-    std::string cmd = android::base::StringPrintf("exec:pm install-create -S %" PRIu64, total_size);
+    std::string install_cmd;
+    if (_use_legacy_install()) {
+        install_cmd = "exec:pm";
+    } else {
+        install_cmd = "exec:cmd package";
+    }
+
+    std::string cmd = android::base::StringPrintf("%s install-create -S %" PRIu64, install_cmd.c_str(), total_size);
     for (i = 1; i < first_apk; i++) {
         cmd += " " + escape_arg(argv[i]);
     }
@@ -2098,8 +2100,8 @@
         }
 
         std::string cmd = android::base::StringPrintf(
-                "exec:pm install-write -S %" PRIu64 " %d %d_%s -",
-                static_cast<uint64_t>(sb.st_size), session_id, i, adb_basename(file).c_str());
+                "%s install-write -S %" PRIu64 " %d %d_%s -",
+                install_cmd.c_str(), static_cast<uint64_t>(sb.st_size), session_id, i, adb_basename(file).c_str());
 
         int localFd = adb_open(file, O_RDONLY);
         if (localFd < 0) {
@@ -2134,8 +2136,8 @@
 finalize_session:
     // Commit session if we streamed everything okay; otherwise abandon
     std::string service =
-            android::base::StringPrintf("exec:pm install-%s %d",
-                                        success ? "commit" : "abandon", session_id);
+            android::base::StringPrintf("%s install-%s %d",
+                                        install_cmd.c_str(), success ? "commit" : "abandon", session_id);
     fd = adb_connect(service, &error);
     if (fd < 0) {
         fprintf(stderr, "Connect error for finalize: %s\n", error.c_str());
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index 4f3e1f5..1f5a258 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -99,7 +99,8 @@
     int fd = -1;
 
 #if ADB_HOST
-    if (find_emulator_transport_by_adb_port(adb_port) != nullptr) {
+    if (find_emulator_transport_by_adb_port(adb_port) != nullptr ||
+        find_emulator_transport_by_console_port(console_port) != nullptr) {
         return -1;
     }
 
@@ -116,7 +117,7 @@
         D("client: connected on remote on fd %d", fd);
         close_on_exec(fd);
         disable_tcp_nagle(fd);
-        std::string serial = android::base::StringPrintf("emulator-%d", console_port);
+        std::string serial = getEmulatorSerialString(console_port);
         if (register_socket_transport(fd, serial.c_str(), adb_port, 1) == 0) {
             return 0;
         }
@@ -360,6 +361,11 @@
     return NULL;
 }
 
+std::string getEmulatorSerialString(int console_port)
+{
+    return android::base::StringPrintf("emulator-%d", console_port);
+}
+
 atransport* find_emulator_transport_by_adb_port(int adb_port)
 {
     adb_mutex_lock( &local_transports_lock );
@@ -368,6 +374,12 @@
     return result;
 }
 
+atransport* find_emulator_transport_by_console_port(int console_port)
+{
+    return find_transport(getEmulatorSerialString(console_port).c_str());
+}
+
+
 /* Only call this function if you already hold local_transports_lock. */
 int get_available_local_transport_index_locked()
 {
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index fa983fa..dfdf29c 100644
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -368,6 +368,7 @@
     ALOGE("Cannot get siginfo for %d: %s\n", tid, strerror(errno));
   }
 
+  ScopedBacktraceMapIteratorLock lock(map);
   _LOG(log, logtype::MAPS, "\n");
   if (!print_fault_address_marker) {
     _LOG(log, logtype::MAPS, "memory map:\n");
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index c1c3174..2b6cad1 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -116,16 +116,18 @@
 };
 
 static std::string find_item_given_name(const char* img_name, const char* product) {
-    char *dir;
-    char path[PATH_MAX + 128];
+    char path_c_str[PATH_MAX + 128];
 
     if(product) {
-        get_my_path(path);
-        return android::base::StringPrintf("../../../target/product/%s/%s", product, img_name);
+        get_my_path(path_c_str);
+        std::string path = path_c_str;
+        path.erase(path.find_last_of('/'));
+        return android::base::StringPrintf("%s/../../../target/product/%s/%s",
+                                           path.c_str(), product, img_name);
     }
 
-    dir = getenv("ANDROID_PRODUCT_OUT");
-    if((dir == 0) || (dir[0] == 0)) {
+    char *dir = getenv("ANDROID_PRODUCT_OUT");
+    if (dir == nullptr || dir[0] == '\0') {
         die("neither -p product specified nor ANDROID_PRODUCT_OUT set");
     }
 
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index 6de8817..387f708 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -489,7 +489,7 @@
  * first successful mount.
  * Returns -1 on error, and  FS_MGR_MNTALL_* otherwise.
  */
-int fs_mgr_mount_all(struct fstab *fstab)
+int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
 {
     int i = 0;
     int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE;
@@ -503,8 +503,10 @@
     }
 
     for (i = 0; i < fstab->num_entries; i++) {
-        /* Don't mount entries that are managed by vold */
-        if (fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) {
+        /* Don't mount entries that are managed by vold or not for the mount mode*/
+        if ((fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) ||
+             ((mount_mode == MOUNT_MODE_LATE) && !fs_mgr_is_latemount(&fstab->recs[i])) ||
+             ((mount_mode == MOUNT_MODE_EARLY) && fs_mgr_is_latemount(&fstab->recs[i]))) {
             continue;
         }
 
diff --git a/fs_mgr/fs_mgr_fstab.c b/fs_mgr/fs_mgr_fstab.c
index 45adb34..21b4c74 100644
--- a/fs_mgr/fs_mgr_fstab.c
+++ b/fs_mgr/fs_mgr_fstab.c
@@ -78,6 +78,7 @@
     { "formattable", MF_FORMATTABLE },
     { "slotselect",  MF_SLOTSELECT },
     { "nofail",      MF_NOFAIL },
+    { "latemount",   MF_LATEMOUNT },
     { "defaults",    0 },
     { 0,             0 },
 };
@@ -545,3 +546,8 @@
 {
     return fstab->fs_mgr_flags & MF_NOFAIL;
 }
+
+int fs_mgr_is_latemount(struct fstab_rec *fstab)
+{
+    return fstab->fs_mgr_flags & MF_LATEMOUNT;
+}
diff --git a/fs_mgr/fs_mgr_main.c b/fs_mgr/fs_mgr_main.c
index e5a00d5..776c13e 100644
--- a/fs_mgr/fs_mgr_main.c
+++ b/fs_mgr/fs_mgr_main.c
@@ -96,7 +96,7 @@
     fstab = fs_mgr_read_fstab(fstab_file);
 
     if (a_flag) {
-        return fs_mgr_mount_all(fstab);
+        return fs_mgr_mount_all(fstab, MOUNT_MODE_DEFAULT);
     } else if (n_flag) {
         return fs_mgr_do_mount(fstab, n_name, n_blk_dev, 0);
     } else if (u_flag) {
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 46975f1..6d9492b 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -48,7 +48,7 @@
  *
  *   <fs_mgr_options> is a comma separated list of flags that control the operation of
  *                     the fs_mgr program.  The list includes "wait", which will wait till
- *                     the <source> file exists, and "check", which requests that the fs_mgr 
+ *                     the <source> file exists, and "check", which requests that the fs_mgr
  *                     run an fscheck program on the <source> before mounting the filesystem.
  *                     If check is specifed on a read-only filesystem, it is ignored.
  *                     Also, "encryptable" means that filesystem can be encrypted.
@@ -83,6 +83,7 @@
 #define MF_FORMATTABLE  0x4000
 #define MF_SLOTSELECT   0x8000
 #define MF_FORCEFDEORFBE 0x10000
+#define MF_LATEMOUNT    0x20000
 #define MF_NOFAIL       0x40000
 
 #define DM_BUF_SIZE 4096
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 46d8f97..7565965 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -40,6 +40,13 @@
     VERITY_MODE_DEFAULT = VERITY_MODE_RESTART
 };
 
+// Mount modes
+enum mount_mode {
+    MOUNT_MODE_DEFAULT = 0,
+    MOUNT_MODE_EARLY = 1,
+    MOUNT_MODE_LATE = 2
+};
+
 /*
  * The entries must be kept in the same order as they were seen in the fstab.
  * Unless explicitly requested, a lookup on mount point should always
@@ -82,7 +89,7 @@
 #define FS_MGR_MNTALL_DEV_NOT_ENCRYPTED 1
 #define FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE 0
 #define FS_MGR_MNTALL_FAIL -1
-int fs_mgr_mount_all(struct fstab *fstab);
+int fs_mgr_mount_all(struct fstab *fstab, int mount_mode);
 
 #define FS_MGR_DOMNT_FAILED -1
 #define FS_MGR_DOMNT_BUSY -2
@@ -110,6 +117,7 @@
 int fs_mgr_is_notrim(struct fstab_rec *fstab);
 int fs_mgr_is_formattable(struct fstab_rec *fstab);
 int fs_mgr_is_nofail(struct fstab_rec *fstab);
+int fs_mgr_is_latemount(struct fstab_rec *fstab);
 int fs_mgr_swapon_all(struct fstab *fstab);
 
 int fs_mgr_do_format(struct fstab_rec *fstab);
diff --git a/healthd/healthd.cpp b/healthd/healthd.cpp
index d9ac356..2caae78 100644
--- a/healthd/healthd.cpp
+++ b/healthd/healthd.cpp
@@ -136,10 +136,14 @@
     struct android::BatteryProperties* /*props*/) {
 }
 
-int healthd_register_event(int fd, void (*handler)(uint32_t)) {
+int healthd_register_event(int fd, void (*handler)(uint32_t), EventWakeup wakeup) {
     struct epoll_event ev;
 
-    ev.events = EPOLLIN | EPOLLWAKEUP;
+    ev.events = EPOLLIN;
+
+    if (wakeup == EVENT_WAKEUP_FD)
+        ev.events |= EPOLLWAKEUP;
+
     ev.data.ptr = (void *)handler;
     if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) {
         KLOG_ERROR(LOG_TAG,
@@ -245,7 +249,7 @@
     }
 
     fcntl(uevent_fd, F_SETFL, O_NONBLOCK);
-    if (healthd_register_event(uevent_fd, uevent_event))
+    if (healthd_register_event(uevent_fd, uevent_event, EVENT_WAKEUP_FD))
         KLOG_ERROR(LOG_TAG,
                    "register for uevent events failed\n");
 }
@@ -268,7 +272,7 @@
         return;
     }
 
-    if (healthd_register_event(wakealarm_fd, wakealarm_event))
+    if (healthd_register_event(wakealarm_fd, wakealarm_event, EVENT_WAKEUP_FD))
         KLOG_ERROR(LOG_TAG,
                    "Registration of wakealarm event failed\n");
 
@@ -286,7 +290,6 @@
         if (timeout < 0 || (mode_timeout > 0 && mode_timeout < timeout))
             timeout = mode_timeout;
         nevents = epoll_wait(epollfd, events, eventct, timeout);
-
         if (nevents == -1) {
             if (errno == EINTR)
                 continue;
diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp
index 5846626..a6da704 100644
--- a/healthd/healthd_mode_charger.cpp
+++ b/healthd/healthd_mode_charger.cpp
@@ -686,7 +686,7 @@
     ret = ev_init(input_callback, charger);
     if (!ret) {
         epollfd = ev_get_epollfd();
-        healthd_register_event(epollfd, charger_event_handler);
+        healthd_register_event(epollfd, charger_event_handler, EVENT_WAKEUP_FD);
     }
 
     ret = res_create_display_surface("charger/battery_fail", &charger->surf_unknown);
diff --git a/healthd/include/healthd/healthd.h b/healthd/include/healthd/healthd.h
index 34ea55f..17efbd6 100644
--- a/healthd/include/healthd/healthd.h
+++ b/healthd/include/healthd/healthd.h
@@ -73,9 +73,14 @@
     bool (*screen_on)(android::BatteryProperties *props);
 };
 
+enum EventWakeup {
+    EVENT_NO_WAKEUP_FD,
+    EVENT_WAKEUP_FD,
+};
+
 // Global helper functions
 
-int healthd_register_event(int fd, void (*handler)(uint32_t));
+int healthd_register_event(int fd, void (*handler)(uint32_t), EventWakeup wakeup = EVENT_NO_WAKEUP_FD);
 void healthd_battery_update();
 android::status_t healthd_get_property(int id,
     struct android::BatteryProperty *val);
diff --git a/include/backtrace/BacktraceMap.h b/include/backtrace/BacktraceMap.h
index 2373c45..b80045f 100644
--- a/include/backtrace/BacktraceMap.h
+++ b/include/backtrace/BacktraceMap.h
@@ -71,6 +71,12 @@
   bool IsWritable(uintptr_t pc) { return GetFlags(pc) & PROT_WRITE; }
   bool IsExecutable(uintptr_t pc) { return GetFlags(pc) & PROT_EXEC; }
 
+  // In order to use the iterators on this object, a caller must
+  // call the LockIterator and UnlockIterator function to guarantee
+  // that the data does not change while it's being used.
+  virtual void LockIterator() {}
+  virtual void UnlockIterator() {}
+
   typedef std::deque<backtrace_map_t>::iterator iterator;
   iterator begin() { return maps_.begin(); }
   iterator end() { return maps_.end(); }
@@ -102,4 +108,18 @@
   pid_t pid_;
 };
 
+class ScopedBacktraceMapIteratorLock {
+public:
+  explicit ScopedBacktraceMapIteratorLock(BacktraceMap* map) : map_(map) {
+    map->LockIterator();
+  }
+
+  ~ScopedBacktraceMapIteratorLock() {
+    map_->UnlockIterator();
+  }
+
+private:
+  BacktraceMap* map_;
+};
+
 #endif // _BACKTRACE_BACKTRACE_MAP_H
diff --git a/include/cutils/trace.h b/include/cutils/trace.h
index c9790ad..19313af 100644
--- a/include/cutils/trace.h
+++ b/include/cutils/trace.h
@@ -70,7 +70,8 @@
 #define ATRACE_TAG_PACKAGE_MANAGER  (1<<18)
 #define ATRACE_TAG_SYSTEM_SERVER    (1<<19)
 #define ATRACE_TAG_DATABASE         (1<<20)
-#define ATRACE_TAG_LAST             ATRACE_TAG_DATABASE
+#define ATRACE_TAG_NETWORK          (1<<21)
+#define ATRACE_TAG_LAST             ATRACE_TAG_NETWORK
 
 // Reserved for initialization.
 #define ATRACE_TAG_NOT_READY        (1ULL<<63)
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 70f9194..44217f0 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -479,9 +479,9 @@
  *
  * start_index: index of the first path in the args list
  */
-static void import_late(const std::vector<std::string>& args, size_t start_index) {
+static void import_late(const std::vector<std::string>& args, size_t start_index, size_t end_index) {
     Parser& parser = Parser::GetInstance();
-    if (args.size() <= start_index) {
+    if (end_index <= start_index) {
         // Use the default set if no path is given
         static const std::vector<std::string> init_directories = {
             "/system/etc/init",
@@ -493,25 +493,23 @@
             parser.ParseConfig(dir);
         }
     } else {
-        for (size_t i = start_index; i < args.size(); ++i) {
+        for (size_t i = start_index; i < end_index; ++i) {
             parser.ParseConfig(args[i]);
         }
     }
 }
 
-/* mount_all <fstab> [ <path> ]*
+/* mount_fstab
  *
- * This function might request a reboot, in which case it will
- * not return.
+ *  Call fs_mgr_mount_all() to mount the given fstab
  */
-static int do_mount_all(const std::vector<std::string>& args) {
+static int mount_fstab(const char* fstabfile, int mount_mode) {
     pid_t pid;
     int ret = -1;
     int child_ret = -1;
     int status;
     struct fstab *fstab;
 
-    const char* fstabfile = args[1].c_str();
     /*
      * Call fs_mgr_mount_all() to mount all filesystems.  We fork(2) and
      * do the call in the child to provide protection to the main init
@@ -536,7 +534,7 @@
         /* child, call fs_mgr_mount_all() */
         klog_set_level(6);  /* So we can see what fs_mgr_mount_all() does */
         fstab = fs_mgr_read_fstab(fstabfile);
-        child_ret = fs_mgr_mount_all(fstab);
+        child_ret = fs_mgr_mount_all(fstab, mount_mode);
         fs_mgr_free_fstab(fstab);
         if (child_ret == -1) {
             ERROR("fs_mgr_mount_all returned an error\n");
@@ -546,28 +544,38 @@
         /* fork failed, return an error */
         return -1;
     }
+    return ret;
+}
 
-    /* Paths of .rc files are specified at the 2nd argument and beyond */
-    import_late(args, 2);
-
-    if (ret == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) {
+/* Queue event based on fs_mgr return code.
+ *
+ * code: return code of fs_mgr_mount_all
+ *
+ * This function might request a reboot, in which case it will
+ * not return.
+ *
+ * return code is processed based on input code
+ */
+static int queue_fs_event(int code) {
+    int ret = code;
+    if (code == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) {
         ActionManager::GetInstance().QueueEventTrigger("encrypt");
-    } else if (ret == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) {
+    } else if (code == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) {
         property_set("ro.crypto.state", "encrypted");
         property_set("ro.crypto.type", "block");
         ActionManager::GetInstance().QueueEventTrigger("defaultcrypto");
-    } else if (ret == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
+    } else if (code == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
         property_set("ro.crypto.state", "unencrypted");
         ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
-    } else if (ret == FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
+    } else if (code == FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
         property_set("ro.crypto.state", "unsupported");
         ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
-    } else if (ret == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) {
+    } else if (code == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) {
         /* Setup a wipe via recovery, and reboot into recovery */
         ERROR("fs_mgr_mount_all suggested recovery, so wiping data via recovery.\n");
         ret = wipe_data_via_recovery("wipe_data_via_recovery");
         /* If reboot worked, there is no return. */
-    } else if (ret == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
+    } else if (code == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
         if (e4crypt_install_keyring()) {
             return -1;
         }
@@ -577,14 +585,55 @@
         // Although encrypted, we have device key, so we do not need to
         // do anything different from the nonencrypted case.
         ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
-    } else if (ret > 0) {
-        ERROR("fs_mgr_mount_all returned unexpected error %d\n", ret);
+    } else if (code > 0) {
+        ERROR("fs_mgr_mount_all returned unexpected error %d\n", code);
     }
     /* else ... < 0: error */
 
     return ret;
 }
 
+/* mount_all <fstab> [ <path> ]* [--<options>]*
+ *
+ * This function might request a reboot, in which case it will
+ * not return.
+ */
+static int do_mount_all(const std::vector<std::string>& args) {
+    std::size_t na = 0;
+    bool import_rc = true;
+    bool queue_event = true;
+    int mount_mode = MOUNT_MODE_DEFAULT;
+    const char* fstabfile = args[1].c_str();
+    std::size_t path_arg_end = args.size();
+
+    for (na = args.size() - 1; na > 1; --na) {
+        if (args[na] == "--early") {
+             path_arg_end = na;
+             queue_event = false;
+             mount_mode = MOUNT_MODE_EARLY;
+        } else if (args[na] == "--late") {
+            path_arg_end = na;
+            import_rc = false;
+            mount_mode = MOUNT_MODE_LATE;
+        }
+    }
+
+    int ret =  mount_fstab(fstabfile, mount_mode);
+
+    if (import_rc) {
+        /* Paths of .rc files are specified at the 2nd argument and beyond */
+        import_late(args, 2, path_arg_end);
+    }
+
+    if (queue_event) {
+        /* queue_fs_event will queue event based on mount_fstab return code
+         * and return processed return code*/
+        ret = queue_fs_event(ret);
+    }
+
+    return ret;
+}
+
 static int do_swapon_all(const std::vector<std::string>& args) {
     struct fstab *fstab;
     int ret;
diff --git a/init/init_parser.cpp b/init/init_parser.cpp
index b44ca59..f2e5d6d 100644
--- a/init/init_parser.cpp
+++ b/init/init_parser.cpp
@@ -122,14 +122,20 @@
         return false;
     }
     dirent* current_file;
+    std::vector<std::string> files;
     while ((current_file = readdir(config_dir.get()))) {
-        std::string current_path =
-            android::base::StringPrintf("%s/%s", path.c_str(), current_file->d_name);
         // Ignore directories and only process regular files.
         if (current_file->d_type == DT_REG) {
-            if (!ParseConfigFile(current_path)) {
-                ERROR("could not import file '%s'\n", current_path.c_str());
-            }
+            std::string current_path =
+                android::base::StringPrintf("%s/%s", path.c_str(), current_file->d_name);
+            files.emplace_back(current_path);
+        }
+    }
+    // Sort first so we load files in a consistent order (bug 31996208)
+    std::sort(files.begin(), files.end());
+    for (const auto& file : files) {
+        if (!ParseConfigFile(file)) {
+            ERROR("Could not import file '%s'\n", file.c_str());
         }
     }
     return true;
diff --git a/init/readme.txt b/init/readme.txt
index 4481e24..dad7e06 100644
--- a/init/readme.txt
+++ b/init/readme.txt
@@ -1,4 +1,3 @@
-
 Android Init Language
 ---------------------
 
@@ -78,6 +77,14 @@
 conflict resolution when multiple services are added to the system, as
 each one will go into a separate file.
 
+There are two options "early" and "late" in mount_all command
+which can be set after optional paths. With "--early" set, the
+init executable will skip mounting entries with "latemount" flag
+and triggering fs encryption state event. With "--late" set,
+init executable will only mount entries with "latemount" flag but skip
+importing rc files. By default, no option is set, and mount_all will
+mount_all will process all entries in the given fstab.
+
 Actions
 -------
 Actions are named sequences of commands.  Actions have a trigger which
@@ -291,10 +298,11 @@
    owned by the root user and root group. If provided, the mode, owner and group
    will be updated if the directory exists already.
 
-mount_all <fstab> [ <path> ]*
+mount_all <fstab> [ <path> ]* [--<option>]
    Calls fs_mgr_mount_all on the given fs_mgr-format fstab and imports .rc files
-   at the specified paths (e.g., on the partitions just mounted). Refer to the
-   section of "Init .rc Files" for detail.
+   at the specified paths (e.g., on the partitions just mounted) with optional
+   options "early" and "late".
+   Refer to the section of "Init .rc Files" for detail.
 
 mount <type> <device> <dir> [ <flag> ]* [<options>]
    Attempt to mount the named device at the directory <dir>
diff --git a/libbacktrace/BacktraceMap.cpp b/libbacktrace/BacktraceMap.cpp
index ba86632..85f2436 100644
--- a/libbacktrace/BacktraceMap.cpp
+++ b/libbacktrace/BacktraceMap.cpp
@@ -35,8 +35,8 @@
 }
 
 void BacktraceMap::FillIn(uintptr_t addr, backtrace_map_t* map) {
-  for (BacktraceMap::const_iterator it = begin();
-       it != end(); ++it) {
+  ScopedBacktraceMapIteratorLock lock(this);
+  for (BacktraceMap::const_iterator it = begin(); it != end(); ++it) {
     if (addr >= it->start && addr < it->end) {
       *map = *it;
       return;
diff --git a/libbacktrace/UnwindMap.cpp b/libbacktrace/UnwindMap.cpp
index 34d79f9..af79562 100644
--- a/libbacktrace/UnwindMap.cpp
+++ b/libbacktrace/UnwindMap.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <pthread.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <sys/types.h>
@@ -72,6 +73,7 @@
 }
 
 UnwindMapLocal::UnwindMapLocal() : UnwindMap(getpid()), map_created_(false) {
+  pthread_rwlock_init(&map_lock_, nullptr);
 }
 
 UnwindMapLocal::~UnwindMapLocal() {
@@ -82,9 +84,14 @@
 }
 
 bool UnwindMapLocal::GenerateMap() {
+  // Lock so that multiple threads cannot modify the maps data at the
+  // same time.
+  pthread_rwlock_wrlock(&map_lock_);
+
   // It's possible for the map to be regenerated while this loop is occurring.
   // If that happens, get the map again, but only try at most three times
   // before giving up.
+  bool generated = false;
   for (int i = 0; i < 3; i++) {
     maps_.clear();
 
@@ -110,12 +117,17 @@
     }
     // Check to see if the map changed while getting the data.
     if (ret != -UNW_EINVAL) {
-      return true;
+      generated = true;
+      break;
     }
   }
 
-  BACK_LOGW("Unable to generate the map.");
-  return false;
+  pthread_rwlock_unlock(&map_lock_);
+
+  if (!generated) {
+    BACK_LOGW("Unable to generate the map.");
+  }
+  return generated;
 }
 
 bool UnwindMapLocal::Build() {
diff --git a/libbacktrace/UnwindMap.h b/libbacktrace/UnwindMap.h
index 111401f..f85b54a 100644
--- a/libbacktrace/UnwindMap.h
+++ b/libbacktrace/UnwindMap.h
@@ -17,6 +17,7 @@
 #ifndef _LIBBACKTRACE_UNWIND_MAP_H
 #define _LIBBACKTRACE_UNWIND_MAP_H
 
+#include <pthread.h>
 #include <stdint.h>
 #include <sys/types.h>
 
@@ -56,10 +57,15 @@
 
   void FillIn(uintptr_t addr, backtrace_map_t* map) override;
 
+  void LockIterator() override { pthread_rwlock_rdlock(&map_lock_); }
+  void UnlockIterator() override { pthread_rwlock_unlock(&map_lock_); }
+
 private:
   bool GenerateMap();
 
   bool map_created_;
+
+  pthread_rwlock_t map_lock_;
 };
 
 #endif // _LIBBACKTRACE_UNWIND_MAP_H
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index f6b2591..913e12d 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -896,6 +896,7 @@
   std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(pid));
 
   // Basic test that verifies that the map is in the expected order.
+  ScopedBacktraceMapIteratorLock lock(map.get());
   std::vector<map_test_t>::const_iterator test_it = test_maps.begin();
   for (BacktraceMap::const_iterator it = map->begin(); it != map->end(); ++it) {
     ASSERT_TRUE(test_it != test_maps.end());
diff --git a/liblog/event_tag_map.c b/liblog/event_tag_map.c
index 3cb04cf..345f0d3 100644
--- a/liblog/event_tag_map.c
+++ b/liblog/event_tag_map.c
@@ -99,6 +99,9 @@
     if (processFile(newTagMap) != 0)
         goto fail;
 
+    if (fd >= 0)
+      close(fd);
+
     return newTagMap;
 
 fail:
diff --git a/liblog/pmsg_writer.c b/liblog/pmsg_writer.c
index b338dca..944feba 100644
--- a/liblog/pmsg_writer.c
+++ b/liblog/pmsg_writer.c
@@ -31,8 +31,6 @@
 #include <private/android_filesystem_config.h>
 #include <private/android_logger.h>
 
-#include <sys/system_properties.h>
-
 #include "config_write.h"
 #include "log_portability.h"
 #include "logger.h"
@@ -53,25 +51,8 @@
     .write = pmsgWrite,
 };
 
-static bool pmsgShouldUse = false;
-
-// Only use pmsg on eng builds
-static bool pmsgIsEng() {
-    char buf[PROP_VALUE_MAX];
-
-    if (__system_property_get("ro.build.type", buf) == 0) {
-        return false;
-    }
-
-    if (!strncmp(buf, "eng", sizeof("eng"))) {
-        return true;
-    }
-    return false;
-}
-
 static int pmsgOpen()
 {
-    pmsgShouldUse = pmsgIsEng();
     if (pmsgLoggerWrite.context.fd < 0) {
         pmsgLoggerWrite.context.fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
     }
@@ -94,7 +75,7 @@
     }
     if ((logId != LOG_ID_SECURITY) &&
             (logId != LOG_ID_EVENTS) &&
-            (!pmsgShouldUse || !__android_log_is_debuggable())) {
+            !__android_log_is_debuggable()) {
         return -EINVAL;
     }
     if (pmsgLoggerWrite.context.fd < 0) {
@@ -124,7 +105,7 @@
     size_t i, payloadSize;
     ssize_t ret;
 
-    if ((logId == LOG_ID_EVENTS) && (!pmsgShouldUse || !__android_log_is_debuggable())) {
+    if ((logId == LOG_ID_EVENTS) && !__android_log_is_debuggable()) {
         if (vec[0].iov_len < 4) {
             return -EINVAL;
         }
diff --git a/libutils/RefBase.cpp b/libutils/RefBase.cpp
index f90e28b..4ead19c 100644
--- a/libutils/RefBase.cpp
+++ b/libutils/RefBase.cpp
@@ -575,15 +575,14 @@
             // grab a strong-reference, which is always safe due to the
             // extended life-time.
             curCount = impl->mStrong.fetch_add(1, std::memory_order_relaxed);
-        }
-
-        // If the strong reference count has already been incremented by
-        // someone else, the implementor of onIncStrongAttempted() is holding
-        // an unneeded reference.  So call onLastStrongRef() here to remove it.
-        // (No, this is not pretty.)  Note that we MUST NOT do this if we
-        // are in fact acquiring the first reference.
-        if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) {
-            impl->mBase->onLastStrongRef(id);
+            // If the strong reference count has already been incremented by
+            // someone else, the implementor of onIncStrongAttempted() is holding
+            // an unneeded reference.  So call onLastStrongRef() here to remove it.
+            // (No, this is not pretty.)  Note that we MUST NOT do this if we
+            // are in fact acquiring the first reference.
+            if (curCount != 0 && curCount != INITIAL_STRONG_VALUE) {
+                impl->mBase->onLastStrongRef(id);
+            }
         }
     }
     
@@ -593,7 +592,7 @@
     ALOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount);
 #endif
 
-    // curCount is the value of mStrong before we increment ed it.
+    // curCount is the value of mStrong before we incremented it.
     // Now we need to fix-up the count if it was INITIAL_STRONG_VALUE.
     // This must be done safely, i.e.: handle the case where several threads
     // were here in attemptIncStrong().
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 8c30f79..0497a89 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -313,6 +313,9 @@
     LogBufferElement *element = *it;
     log_id_t id = element->getLogId();
 
+    // Remove iterator references in the various lists that will become stale
+    // after the element is erased from the main logging list.
+
     {   // start of scope for uid found iterator
         LogBufferIteratorMap::iterator found =
             mLastWorstUid[id].find(element->getUid());
@@ -322,8 +325,8 @@
         }
     }
 
-    if (element->getUid() == AID_SYSTEM) {
-        // start of scope for pid found iterator
+    {   // start of scope for pid found iterator
+        // element->getUid() may not be AID_SYSTEM for next-best-watermark.
         LogBufferPidIteratorMap::iterator found =
             mLastWorstPidOfSystem[id].find(element->getPid());
         if ((found != mLastWorstPidOfSystem[id].end())
@@ -639,6 +642,7 @@
                 ++it;
                 continue;
             }
+            // below this point element->getLogId() == id
 
             if (leading && (!mLastSet[id] || ((*mLast[id])->getLogId() != id))) {
                 mLast[id] = it;
@@ -691,7 +695,9 @@
                         && ((!gc && (element->getPid() == worstPid))
                             || (mLastWorstPidOfSystem[id].find(element->getPid())
                                 == mLastWorstPidOfSystem[id].end()))) {
-                    mLastWorstPidOfSystem[id][element->getUid()] = it;
+                    // element->getUid() may not be AID_SYSTEM, next best
+                    // watermark if current one empty.
+                    mLastWorstPidOfSystem[id][element->getPid()] = it;
                 }
                 if ((!gc && !worstPid && (element->getUid() == worst))
                         || (mLastWorstUid[id].find(element->getUid())
@@ -709,6 +715,8 @@
                 ++it;
                 continue;
             }
+            // key == worst below here
+            // If worstPid set, then element->getPid() == worstPid below here
 
             pruneRows--;
             if (pruneRows == 0) {
@@ -732,6 +740,8 @@
                     if (worstPid && (!gc
                                 || (mLastWorstPidOfSystem[id].find(worstPid)
                                     == mLastWorstPidOfSystem[id].end()))) {
+                        // element->getUid() may not be AID_SYSTEM, next best
+                        // watermark if current one empty.
                         mLastWorstPidOfSystem[id][worstPid] = it;
                     }
                     if ((!gc && !worstPid) || (mLastWorstUid[id].find(worst)
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 71f9d5a..a22d5c1 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -236,6 +236,9 @@
 
     export DOWNLOAD_CACHE /data/cache
 
+    # set RLIMIT_NICE to allow priorities from 19 to -20
+    setrlimit 13 40 40
+
 # Healthd can trigger a full boot from charger mode by signaling this
 # property when the power button is held.
 on property:sys.boot_from_charger_mode=1
@@ -258,6 +261,11 @@
 # Mount filesystems and start core system services.
 on late-init
     trigger early-fs
+
+    # Mount fstab in init.{$device}.rc by mount_all command. Optional parameter
+    # '--early' can be specified to skip entries with 'latemount'.
+    # /system and /vendor must be mounted by the end of the fs stage,
+    # while /data is optional.
     trigger fs
     trigger post-fs
 
@@ -266,9 +274,18 @@
     # issued fs triggers have completed.
     trigger load_system_props_action
 
+    # Mount fstab in init.{$device}.rc by mount_all with '--late' parameter
+    # to only mount entries with 'latemount'. This is needed if '--early' is
+    # specified in the previous mount_all command on the fs stage.
+    # With /system mounted and properties form /system + /factory available,
+    # some services can be started.
+    trigger late-fs
+
     # Now we can mount /data. File encryption requires keymaster to decrypt
-    # /data, which in turn can only be loaded when system properties are present
+    # /data, which in turn can only be loaded when system properties are present.
     trigger post-fs-data
+
+    # Load persist properties and override properties (if enabled) from /data.
     trigger load_persist_props_action
 
     # Remove a file to wake up anything waiting for firmware.
@@ -480,9 +497,6 @@
     hostname localhost
     domainname localdomain
 
-    # set RLIMIT_NICE to allow priorities from 19 to -20
-    setrlimit 13 40 40
-
     # Memory management.  Basic kernel parameters, and allow the high
     # level system server to be able to adjust the kernel OOM driver
     # parameters to match how it is managing things.
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c
index 9480e4a..13ebaf1 100644
--- a/sdcard/sdcard.c
+++ b/sdcard/sdcard.c
@@ -1221,7 +1221,13 @@
     }
     out.fh = ptr_to_id(h);
     out.open_flags = 0;
+
+#ifdef FUSE_SHORTCIRCUIT
+    out.lower_fd = h->fd;
+#else
     out.padding = 0;
+#endif
+
     fuse_reply(fuse, hdr->unique, &out, sizeof(out));
     return NO_STATUS;
 }
@@ -1385,7 +1391,13 @@
     }
     out.fh = ptr_to_id(h);
     out.open_flags = 0;
+
+#ifdef FUSE_SHORTCIRCUIT
+    out.lower_fd = -1;
+#else
     out.padding = 0;
+#endif
+
     fuse_reply(fuse, hdr->unique, &out, sizeof(out));
     return NO_STATUS;
 }
@@ -1467,6 +1479,11 @@
     out.major = FUSE_KERNEL_VERSION;
     out.max_readahead = req->max_readahead;
     out.flags = FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES;
+
+#ifdef FUSE_SHORTCIRCUIT
+    out.flags |= FUSE_SHORTCIRCUIT;
+#endif
+
     out.max_background = 32;
     out.congestion_threshold = 32;
     out.max_write = MAX_WRITE;