Merge "fs_mgr: overlayfs_mount_scratch don't write to system_other"
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index 5167481..10f52f4 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -150,6 +150,7 @@
     shared_libs: [
         "libbase",
         "libcutils",
+        "libprocinfo",
     ],
 
     export_header_lib_headers: ["libdebuggerd_common_headers"],
diff --git a/debuggerd/client/debuggerd_client.cpp b/debuggerd/client/debuggerd_client.cpp
index 77f3515..610b96b 100644
--- a/debuggerd/client/debuggerd_client.cpp
+++ b/debuggerd/client/debuggerd_client.cpp
@@ -33,6 +33,7 @@
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
 #include <cutils/sockets.h>
+#include <procinfo/process.h>
 
 #include "debuggerd/handler.h"
 #include "protocol.h"
@@ -62,8 +63,20 @@
   tv->tv_usec = static_cast<long>(microseconds.count());
 }
 
-bool debuggerd_trigger_dump(pid_t pid, DebuggerdDumpType dump_type, unsigned int timeout_ms,
+bool debuggerd_trigger_dump(pid_t tid, DebuggerdDumpType dump_type, unsigned int timeout_ms,
                             unique_fd output_fd) {
+  pid_t pid = tid;
+  if (dump_type == kDebuggerdJavaBacktrace) {
+    // Java dumps always get sent to the tgid, so we need to resolve our tid to a tgid.
+    android::procinfo::ProcessInfo procinfo;
+    std::string error;
+    if (!android::procinfo::GetProcessInfo(tid, &procinfo, &error)) {
+      LOG(ERROR) << "libdebugged_client: failed to get process info: " << error;
+      return false;
+    }
+    pid = procinfo.pid;
+  }
+
   LOG(INFO) << "libdebuggerd_client: started dumping process " << pid;
   unique_fd sockfd;
   const auto end = std::chrono::steady_clock::now() + std::chrono::milliseconds(timeout_ms);
@@ -162,7 +175,7 @@
     return false;
   }
 
-  if (!send_signal(pid, dump_type)) {
+  if (!send_signal(tid, dump_type)) {
     return false;
   }
 
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index 824511e..1616a61 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -92,6 +92,7 @@
     name: "libfstab",
     vendor_available: true,
     recovery_available: true,
+    host_supported: true,
     defaults: ["fs_mgr_defaults"],
     srcs: [
         "fs_mgr_fstab.cpp",
diff --git a/fs_mgr/fs_mgr_dm_linear.cpp b/fs_mgr/fs_mgr_dm_linear.cpp
index 3f075ef..45cbff3 100644
--- a/fs_mgr/fs_mgr_dm_linear.cpp
+++ b/fs_mgr/fs_mgr_dm_linear.cpp
@@ -168,6 +168,19 @@
     return true;
 }
 
+bool CreateLogicalPartition(const std::string& block_device, const LpMetadata& metadata,
+                            const std::string& partition_name, bool force_writable,
+                            const std::chrono::milliseconds& timeout_ms, std::string* path) {
+    for (const auto& partition : metadata.partitions) {
+        if (GetPartitionName(partition) == partition_name) {
+            return CreateLogicalPartition(metadata, partition, force_writable, timeout_ms,
+                                          block_device, path);
+        }
+    }
+    LERROR << "Could not find any partition with name: " << partition_name;
+    return false;
+}
+
 bool CreateLogicalPartition(const std::string& block_device, uint32_t metadata_slot,
                             const std::string& partition_name, bool force_writable,
                             const std::chrono::milliseconds& timeout_ms, std::string* path) {
@@ -176,14 +189,8 @@
         LOG(ERROR) << "Could not read partition table.";
         return true;
     }
-    for (const auto& partition : metadata->partitions) {
-        if (GetPartitionName(partition) == partition_name) {
-            return CreateLogicalPartition(*metadata.get(), partition, force_writable, timeout_ms,
-                                          block_device, path);
-        }
-    }
-    LERROR << "Could not find any partition with name: " << partition_name;
-    return false;
+    return CreateLogicalPartition(block_device, *metadata.get(), partition_name, force_writable,
+                                  timeout_ms, path);
 }
 
 bool DestroyLogicalPartition(const std::string& name, const std::chrono::milliseconds& timeout_ms) {
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index e0891eb..53b47be 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -209,17 +209,12 @@
 }
 
 static uint64_t parse_flags(char* flags, struct flag_list* fl, struct fs_mgr_flag_values* flag_vals,
-                            char* fs_options, int fs_options_len) {
+                            std::string* fs_options) {
     uint64_t f = 0;
     int i;
     char *p;
     char *savep;
 
-    /* initialize fs_options to the null string */
-    if (fs_options && (fs_options_len > 0)) {
-        fs_options[0] = '\0';
-    }
-
     p = strtok_r(flags, ",", &savep);
     while (p) {
         /* Look for the flag "p" in the flag list "fl"
@@ -356,26 +351,20 @@
 
         if (!fl[i].name) {
             if (fs_options) {
-                /* It's not a known flag, so it must be a filesystem specific
-                 * option.  Add it to fs_options if it was passed in.
-                 */
-                strlcat(fs_options, p, fs_options_len);
-                strlcat(fs_options, ",", fs_options_len);
+                // It's not a known flag, so it must be a filesystem specific
+                // option.  Add it to fs_options if it was passed in.
+                if (!fs_options->empty()) {
+                    fs_options->append(",");  // appends a comma if not the first
+                }
+                fs_options->append(p);
             } else {
-                /* fs_options was not passed in, so if the flag is unknown
-                 * it's an error.
-                 */
+                // fs_options was not passed in, so if the flag is unknown it's an error.
                 LERROR << "Warning: unknown flag " << p;
             }
         }
         p = strtok_r(NULL, ",", &savep);
     }
 
-    if (fs_options && fs_options[0]) {
-        /* remove the last trailing comma from the list of options */
-        fs_options[strlen(fs_options) - 1] = '\0';
-    }
-
     return f;
 }
 
@@ -513,8 +502,6 @@
     char *save_ptr, *p;
     Fstab fstab;
     struct fs_mgr_flag_values flag_vals;
-#define FS_OPTIONS_LEN 1024
-    char tmp_fs_options[FS_OPTIONS_LEN];
 
     while ((len = getline(&line, &alloc_len, fstab_file)) != -1) {
         /* if the last character is a newline, shorten the string by 1 byte */
@@ -555,13 +542,7 @@
             LERROR << "Error parsing mount_flags";
             goto err;
         }
-        tmp_fs_options[0] = '\0';
-        entry.flags = parse_flags(p, mount_flags, NULL, tmp_fs_options, FS_OPTIONS_LEN);
-
-        /* fs_options are optional */
-        if (tmp_fs_options[0]) {
-            entry.fs_options = tmp_fs_options;
-        }
+        entry.flags = parse_flags(p, mount_flags, nullptr, &entry.fs_options);
 
         // For /proc/mounts, ignore everything after mnt_freq and mnt_passno
         if (proc_mounts) {
@@ -570,7 +551,7 @@
             LERROR << "Error parsing fs_mgr_options";
             goto err;
         }
-        entry.fs_mgr_flags.val = parse_flags(p, fs_mgr_flags, &flag_vals, NULL, 0);
+        entry.fs_mgr_flags.val = parse_flags(p, fs_mgr_flags, &flag_vals, nullptr);
 
         entry.key_loc = std::move(flag_vals.key_loc);
         entry.key_dir = std::move(flag_vals.key_dir);
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 314eaff..7dae7f1 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -758,8 +758,14 @@
     auto mnt_type = fs_mgr_overlayfs_scratch_mount_type();
     if (partition_exists) {
         if (fs_mgr_overlayfs_mount_scratch(scratch_device, mnt_type)) {
-            if (change) *change = true;
-            return true;
+            if (!fs_mgr_access(kScratchMountPoint + kOverlayTopDir) &&
+                !fs_mgr_filesystem_has_space(kScratchMountPoint)) {
+                // declare it useless, no overrides and no free space
+                fs_mgr_overlayfs_umount_scratch();
+            } else {
+                if (change) *change = true;
+                return true;
+            }
         }
         // partition existed, but was not initialized; fall through to make it.
         errno = 0;
diff --git a/fs_mgr/include/fs_mgr_dm_linear.h b/fs_mgr/include/fs_mgr_dm_linear.h
index f065071..f33fc02 100644
--- a/fs_mgr/include/fs_mgr_dm_linear.h
+++ b/fs_mgr/include/fs_mgr_dm_linear.h
@@ -60,6 +60,12 @@
                             const std::string& partition_name, bool force_writable,
                             const std::chrono::milliseconds& timeout_ms, std::string* path);
 
+// Same as above, but with a given metadata object. Care should be taken that
+// the metadata represents a valid partition layout.
+bool CreateLogicalPartition(const std::string& block_device, const LpMetadata& metadata,
+                            const std::string& partition_name, bool force_writable,
+                            const std::chrono::milliseconds& timeout_ms, std::string* path);
+
 // Destroy the block device for a logical partition, by name. If |timeout_ms|
 // is non-zero, then this will block until the device path has been unlinked.
 bool DestroyLogicalPartition(const std::string& name, const std::chrono::milliseconds& timeout_ms);
diff --git a/fs_mgr/libdm/Android.bp b/fs_mgr/libdm/Android.bp
index 90bce51..fc1aafb 100644
--- a/fs_mgr/libdm/Android.bp
+++ b/fs_mgr/libdm/Android.bp
@@ -18,6 +18,7 @@
     name: "libdm",
     defaults: ["fs_mgr_defaults"],
     recovery_available: true,
+    host_supported: true,
 
     export_include_dirs: ["include"],
 
diff --git a/fs_mgr/libdm/dm.cpp b/fs_mgr/libdm/dm.cpp
index d9786ad..c6a9e0b 100644
--- a/fs_mgr/libdm/dm.cpp
+++ b/fs_mgr/libdm/dm.cpp
@@ -349,7 +349,7 @@
     io->data_size = sizeof(*io);
     io->data_start = 0;
     if (!name.empty()) {
-        strlcpy(io->name, name.c_str(), sizeof(io->name));
+        snprintf(io->name, sizeof(io->name), "%s", name.c_str());
     }
 }
 
diff --git a/fs_mgr/libdm/dm_target.cpp b/fs_mgr/libdm/dm_target.cpp
index 7c18267..cb33eea 100644
--- a/fs_mgr/libdm/dm_target.cpp
+++ b/fs_mgr/libdm/dm_target.cpp
@@ -42,7 +42,7 @@
     struct dm_target_spec* spec = reinterpret_cast<struct dm_target_spec*>(&data[0]);
     spec->sector_start = start();
     spec->length = size();
-    strlcpy(spec->target_type, name().c_str(), sizeof(spec->target_type));
+    snprintf(spec->target_type, sizeof(spec->target_type), "%s", name().c_str());
     spec->next = (uint32_t)data.size();
     return data;
 }
diff --git a/fs_mgr/tests/Android.bp b/fs_mgr/tests/Android.bp
index 5497223..ea12e96 100644
--- a/fs_mgr/tests/Android.bp
+++ b/fs_mgr/tests/Android.bp
@@ -23,7 +23,9 @@
         "libfs_mgr",
         "libfstab",
     ],
-
+    data: [
+        "data/*",
+    ],
     srcs: [
         "fs_mgr_test.cpp",
     ],
diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh
index 9e211e3..160e076 100755
--- a/fs_mgr/tests/adb-remount-test.sh
+++ b/fs_mgr/tests/adb-remount-test.sh
@@ -49,7 +49,7 @@
 Returns: true if device is in adb mode" ]
 inAdb() {
   adb devices |
-    grep -v 'List of devices attached' |
+    grep -v -e 'List of devices attached' -e '^$' |
     if [ -n "${ANDROID_SERIAL}" ]; then
       grep "^${ANDROID_SERIAL}[${SPACE}${TAB}]" > /dev/null
     else
@@ -61,7 +61,17 @@
 
 Returns: true if the command succeeded" ]
 adb_sh() {
-  adb shell "${@}"
+  args=
+  for i in ${@}; do
+    if [ X"${i}" != X"${i#\'}" ]; then
+      args="${args} ${i}"
+    elif [ X"${i}" != X"${i#* }" ]; then
+      args="${args} '${i}'"
+    else
+      args="${args} ${i}"
+    fi
+  done
+  adb shell ${args}
 }
 
 [ "USAGE: adb_date >/dev/stdout
@@ -92,7 +102,7 @@
 
 Returns: true if device is (likely) a debug build" ]
 isDebuggable() {
-  if inAdb && [ 1 -ne "`get_property ro.debuggable`" ]; then
+  if inAdb && [ 1 != "`get_property ro.debuggable`" ]; then
     false
   fi
 }
@@ -363,8 +373,12 @@
   echo "${GREEN}[       OK ]${NORMAL} no overlay present before setup" >&2
 overlayfs_needed=true
 D=`adb_sh cat /proc/mounts </dev/null |
-   skip_administrative_mounts data |
-   cut -s -d' ' -f1`
+   skip_administrative_mounts data`
+if echo "${D}" | grep /dev/root >/dev/null; then
+  D=`echo / /
+     echo "${D}" | grep -v /dev/root`
+fi
+D=`echo "${D}" | cut -s -d' ' -f1`
 D=`adb_sh df -k ${D} </dev/null`
 echo "${D}"
 if [ X"${D}" = X"${D##* 100[%] }" ]; then
diff --git a/fs_mgr/tests/data/fstab.example b/fs_mgr/tests/data/fstab.example
new file mode 100644
index 0000000..1a3dfa1
--- /dev/null
+++ b/fs_mgr/tests/data/fstab.example
@@ -0,0 +1,11 @@
+# Android fstab file.
+
+#<src>                                              <mnt_point>        <type>      <mnt_flags and options>                               <fs_mgr_flags>
+
+/dev/block/bootdevice/by-name/system                /                  ext4        ro,barrier=1                                          wait,slotselect,avb
+/dev/block/bootdevice/by-name/metadata              /metadata          ext4        noatime,nosuid,nodev,discard                          wait,formattable
+/dev/block/bootdevice/by-name/userdata              /data              f2fs        noatime,nosuid,nodev,discard,reserve_root=32768,resgid=1065,fsync_mode=nobarrier       latemount,wait,check,fileencryption=ice,keydirectory=/metadata/vold/metadata_encryption,quota,formattable,sysfs_path=/sys/devices/platform/soc/1d84000.ufshc,reservedsize=128M
+/dev/block/bootdevice/by-name/misc                  /misc              emmc        defaults                                              defaults
+/dev/block/bootdevice/by-name/modem                 /vendor/firmware_mnt          vfat        ro,shortname=lower,uid=1000,gid=1000,dmask=227,fmask=337,context=u:object_r:firmware_file:s0   wait,slotselect
+/devices/platform/soc/a600000.ssusb/a600000.dwc3*   auto               vfat        defaults                                              voldmanaged=usb:auto
+/dev/block/zram0                                    none               swap        defaults                                              zramsize=1073741824,max_comp_streams=8
diff --git a/fs_mgr/tests/fs_mgr_test.cpp b/fs_mgr/tests/fs_mgr_test.cpp
index db01c1e..1922a69 100644
--- a/fs_mgr/tests/fs_mgr_test.cpp
+++ b/fs_mgr/tests/fs_mgr_test.cpp
@@ -24,6 +24,8 @@
 #include <utility>
 #include <vector>
 
+#include <android-base/file.h>
+#include <android-base/properties.h>
 #include <android-base/strings.h>
 #include <fstab/fstab.h>
 #include <gtest/gtest.h>
@@ -201,3 +203,33 @@
         ++i;
     }
 }
+
+TEST(fs_mgr, ReadFstabFromFile_FsOptions) {
+    Fstab fstab;
+    std::string fstab_file = android::base::GetExecutableDirectory() + "/data/fstab.example";
+    EXPECT_TRUE(ReadFstabFromFile(fstab_file, &fstab));
+
+    EXPECT_EQ("/", fstab[0].mount_point);
+    EXPECT_EQ("barrier=1", fstab[0].fs_options);
+
+    EXPECT_EQ("/metadata", fstab[1].mount_point);
+    EXPECT_EQ("discard", fstab[1].fs_options);
+
+    EXPECT_EQ("/data", fstab[2].mount_point);
+    EXPECT_EQ("discard,reserve_root=32768,resgid=1065,fsync_mode=nobarrier", fstab[2].fs_options);
+
+    EXPECT_EQ("/misc", fstab[3].mount_point);
+    EXPECT_EQ("", fstab[3].fs_options);
+
+    EXPECT_EQ("/vendor/firmware_mnt", fstab[4].mount_point);
+    EXPECT_EQ(
+            "shortname=lower,uid=1000,gid=1000,dmask=227,fmask=337,"
+            "context=u:object_r:firmware_file:s0",
+            fstab[4].fs_options);
+
+    EXPECT_EQ("auto", fstab[5].mount_point);
+    EXPECT_EQ("", fstab[5].fs_options);
+
+    EXPECT_EQ("none", fstab[6].mount_point);
+    EXPECT_EQ("", fstab[6].fs_options);
+}
diff --git a/healthd/android.hardware.health@2.0-service.rc b/healthd/android.hardware.health@2.0-service.rc
index dca0ccc..6960c5d 100644
--- a/healthd/android.hardware.health@2.0-service.rc
+++ b/healthd/android.hardware.health@2.0-service.rc
@@ -2,4 +2,5 @@
     class hal
     user system
     group system
+    capabilities WAKE_ALARM
     file /dev/kmsg w
diff --git a/init/service.cpp b/init/service.cpp
index 5aa3764..272809f 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -367,12 +367,19 @@
         return;
     }
 
-    // If we crash > 4 times in 4 minutes, reboot into bootloader.
+    // If we crash > 4 times in 4 minutes, reboot into bootloader or set crashing property
     boot_clock::time_point now = boot_clock::now();
-    if ((flags_ & SVC_CRITICAL) && !(flags_ & SVC_RESTART)) {
+    if (((flags_ & SVC_CRITICAL) || classnames_.count("updatable")) && !(flags_ & SVC_RESTART)) {
         if (now < time_crashed_ + 4min) {
             if (++crash_count_ > 4) {
-                LOG(FATAL) << "critical process '" << name_ << "' exited 4 times in 4 minutes";
+                if (flags_ & SVC_CRITICAL) {
+                    // Aborts into bootloader
+                    LOG(FATAL) << "critical process '" << name_ << "' exited 4 times in 4 minutes";
+                } else {
+                    LOG(ERROR) << "updatable process '" << name_ << "' exited 4 times in 4 minutes";
+                    // Notifies update_verifier and apexd
+                    property_set("ro.init.updatable_crashing", "1");
+                }
             }
         } else {
             time_crashed_ = now;
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index 37afb98..4291212 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -89,6 +89,7 @@
                 "socket_inaddr_any_server_windows.cpp",
                 "socket_network_client_windows.cpp",
                 "sockets_windows.cpp",
+                "trace-host.cpp",
             ],
 
             enabled: true,
diff --git a/libunwindstack/DwarfMemory.cpp b/libunwindstack/DwarfMemory.cpp
index 6ffdc0d..b505900 100644
--- a/libunwindstack/DwarfMemory.cpp
+++ b/libunwindstack/DwarfMemory.cpp
@@ -104,7 +104,6 @@
 
 bool DwarfMemory::AdjustEncodedValue(uint8_t encoding, uint64_t* value) {
   CHECK((encoding & 0x0f) == 0);
-  CHECK(encoding != DW_EH_PE_aligned);
 
   // Handle the encoding.
   switch (encoding) {
diff --git a/libunwindstack/tests/DwarfMemoryTest.cpp b/libunwindstack/tests/DwarfMemoryTest.cpp
index f12d2fe..650e965 100644
--- a/libunwindstack/tests/DwarfMemoryTest.cpp
+++ b/libunwindstack/tests/DwarfMemoryTest.cpp
@@ -54,6 +54,8 @@
   void ReadEncodedValue_overflow();
   template <typename AddressType>
   void ReadEncodedValue_high_bit_set();
+  template <typename AddressType>
+  void ReadEncodedValue_all();
 
   MemoryFake memory_;
   std::unique_ptr<DwarfMemory> dwarf_mem_;
@@ -457,6 +459,27 @@
   ReadEncodedValue_high_bit_set<uint64_t>();
 }
 
+template <typename AddressType>
+void DwarfMemoryTest::ReadEncodedValue_all() {
+  MemoryFakeAlwaysReadZero memory;
+  DwarfMemory dwarf_mem(&memory);
+
+  for (size_t i = 0; i <= 0xff; i++) {
+    uint64_t value;
+    if (dwarf_mem.ReadEncodedValue<AddressType>(static_cast<uint8_t>(i), &value)) {
+      ASSERT_EQ(0U, value);
+    }
+  }
+}
+
+TEST_F(DwarfMemoryTest, ReadEncodedValue_all_uint32_t) {
+  ReadEncodedValue_all<uint32_t>();
+}
+
+TEST_F(DwarfMemoryTest, ReadEncodedValue_all_uint64_t) {
+  ReadEncodedValue_all<uint64_t>();
+}
+
 TEST_F(DwarfMemoryTest, AdjustEncodedValue_absptr) {
   uint64_t value = 0x1234;
   ASSERT_TRUE(dwarf_mem_->AdjustEncodedValue(0x00, &value));
diff --git a/libutils/Android.bp b/libutils/Android.bp
index 600c91c..3e8417e 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -155,7 +155,7 @@
             ],
         },
         linux: {
-            shared_libs: ["libbase"],
+            header_libs: ["libbase_headers"],
             srcs: [
                 "Looper.cpp",
             ],
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 483fc51..0ec6e17 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -544,7 +544,7 @@
 
     mkdir /data/anr 0775 system system
 
-    mkdir /data/apex 0770 root root
+    mkdir /data/apex 0750 root system
     mkdir /data/staging 0750 system system
 
     # NFC: create data/nfc for nv storage
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index 35f469a..451f5ad 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -44,8 +44,6 @@
 /dev/dri/*                0666   root       graphics
 
 # these should not be world writable
-/dev/diag                 0660   radio      radio
-/dev/ttyMSM0              0600   bluetooth  bluetooth
 /dev/uhid                 0660   uhid       uhid
 /dev/uinput               0660   uhid       uhid
 /dev/rtc0                 0640   system     system
@@ -54,7 +52,6 @@
 /dev/input/*              0660   root       input
 /dev/v4l-touch*           0660   root       input
 /dev/snd/*                0660   system     audio
-/dev/msm_mp3*             0660   system     audio
 /dev/bus/usb/*            0660   root       usb
 /dev/mtp_usb              0660   root       mtp
 /dev/usb_accessory        0660   root       usb