Merge "fastboot, fs_mgr: set fsverity feature bit" into pi-dev
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 546321e..872031c 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -73,13 +73,13 @@
 
 DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK(nullptr, nullptr);
 
-static std::string product_file(const char* file) {
+static std::string product_file(const std::string& file) {
     const char* ANDROID_PRODUCT_OUT = getenv("ANDROID_PRODUCT_OUT");
     if (ANDROID_PRODUCT_OUT == nullptr) {
         fprintf(stderr, "adb: product directory not specified; set $ANDROID_PRODUCT_OUT\n");
         exit(1);
     }
-    return android::base::StringPrintf("%s%s%s", ANDROID_PRODUCT_OUT, OS_PATH_SEPARATOR_STR, file);
+    return std::string{ANDROID_PRODUCT_OUT} + OS_PATH_SEPARATOR_STR + file;
 }
 
 static void help() {
@@ -134,7 +134,7 @@
         " pull [-a] REMOTE... LOCAL\n"
         "     copy files/dirs from device\n"
         "     -a: preserve file timestamp and mode\n"
-        " sync [system|vendor|oem|data|all]\n"
+        " sync [all|data|odm|oem|product|system|vendor]\n"
         "     sync a local build from $ANDROID_PRODUCT_OUT to the device (default all)\n"
         "     -l: list but don't copy\n"
         "\n"
@@ -189,8 +189,7 @@
         " get-state                print offline | bootloader | device\n"
         " get-serialno             print <serial-number>\n"
         " get-devpath              print <device-path>\n"
-        " remount\n"
-        "     remount /system, /vendor, and /oem partitions read-write\n"
+        " remount                  remount partitions read-write\n"
         " reboot [bootloader|recovery|sideload|sideload-auto-reboot]\n"
         "     reboot the device; defaults to booting system image but\n"
         "     supports bootloader and recovery too. sideload reboots\n"
@@ -1731,48 +1730,28 @@
         std::string src;
         bool list_only = false;
         if (argc < 2) {
-            // No local path was specified.
-            src = "";
+            // No partition specified: sync all of them.
         } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
             list_only = true;
-            if (argc == 3) {
-                src = argv[2];
-            } else {
-                src = "";
-            }
+            if (argc == 3) src = argv[2];
         } else if (argc == 2) {
-            // A local path or "android"/"data" arg was specified.
             src = argv[1];
         } else {
             return syntax_error("adb sync [-l] [PARTITION]");
         }
 
-        if (src == "all") src = "";
-
-        if (src != "" &&
-            src != "system" && src != "data" && src != "vendor" && src != "oem") {
-            return syntax_error("don't know how to sync %s partition", src.c_str());
+        if (src.empty()) src = "all";
+        std::vector<std::string> partitions{"data", "odm", "oem", "product", "system", "vendor"};
+        bool found = false;
+        for (const auto& partition : partitions) {
+            if (src == "all" || src == partition) {
+                std::string src_dir{product_file(partition)};
+                if (!directory_exists(src_dir)) continue;
+                found = true;
+                if (!do_sync_sync(src_dir, "/" + partition, list_only)) return 1;
+            }
         }
-
-        std::string system_src_path = product_file("system");
-        std::string data_src_path = product_file("data");
-        std::string vendor_src_path = product_file("vendor");
-        std::string oem_src_path = product_file("oem");
-
-        bool okay = true;
-        if (okay && (src.empty() || src == "system")) {
-            okay = do_sync_sync(system_src_path, "/system", list_only);
-        }
-        if (okay && (src.empty() || src == "vendor") && directory_exists(vendor_src_path)) {
-            okay = do_sync_sync(vendor_src_path, "/vendor", list_only);
-        }
-        if (okay && (src.empty() || src == "oem") && directory_exists(oem_src_path)) {
-            okay = do_sync_sync(oem_src_path, "/oem", list_only);
-        }
-        if (okay && (src.empty() || src == "data")) {
-            okay = do_sync_sync(data_src_path, "/data", list_only);
-        }
-        return okay ? 0 : 1;
+        return found ? 0 : syntax_error("don't know how to sync %s partition", src.c_str());
     }
     /* passthrough commands */
     else if (!strcmp(argv[0],"get-state") ||
diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp
index 3c27582..5adeb44 100644
--- a/adb/daemon/main.cpp
+++ b/adb/daemon/main.cpp
@@ -19,10 +19,11 @@
 #include "sysdeps.h"
 
 #include <errno.h>
+#include <getopt.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <getopt.h>
+#include <sys/capability.h>
 #include <sys/prctl.h>
 
 #include <memory>
@@ -49,13 +50,13 @@
 
 static const char* root_seclabel = nullptr;
 
-static void drop_capabilities_bounding_set_if_needed(struct minijail *j) {
+static bool should_drop_capabilities_bounding_set() {
 #if defined(ALLOW_ADBD_ROOT)
     if (__android_log_is_debuggable()) {
-        return;
+        return false;
     }
 #endif
-    minijail_capbset_drop(j, CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SETGID));
+    return true;
 }
 
 static bool should_drop_privileges() {
@@ -116,13 +117,37 @@
     // Don't listen on a port (default 5037) if running in secure mode.
     // Don't run as root if running in secure mode.
     if (should_drop_privileges()) {
-        drop_capabilities_bounding_set_if_needed(jail.get());
+        const bool should_drop_caps = should_drop_capabilities_bounding_set();
+
+        if (should_drop_caps) {
+            minijail_use_caps(jail.get(), CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SETGID));
+        }
 
         minijail_change_gid(jail.get(), AID_SHELL);
         minijail_change_uid(jail.get(), AID_SHELL);
         // minijail_enter() will abort if any priv-dropping step fails.
         minijail_enter(jail.get());
 
+        // Whenever ambient capabilities are being used, minijail cannot
+        // simultaneously drop the bounding capability set to just
+        // CAP_SETUID|CAP_SETGID while clearing the inheritable, effective,
+        // and permitted sets. So we need to do that in two steps.
+        using ScopedCaps =
+            std::unique_ptr<std::remove_pointer<cap_t>::type, std::function<void(cap_t)>>;
+        ScopedCaps caps(cap_get_proc(), &cap_free);
+        if (cap_clear_flag(caps.get(), CAP_INHERITABLE) == -1) {
+            PLOG(FATAL) << "cap_clear_flag(INHERITABLE) failed";
+        }
+        if (cap_clear_flag(caps.get(), CAP_EFFECTIVE) == -1) {
+            PLOG(FATAL) << "cap_clear_flag(PEMITTED) failed";
+        }
+        if (cap_clear_flag(caps.get(), CAP_PERMITTED) == -1) {
+            PLOG(FATAL) << "cap_clear_flag(PEMITTED) failed";
+        }
+        if (cap_set_proc(caps.get()) != 0) {
+            PLOG(FATAL) << "cap_set_proc() failed";
+        }
+
         D("Local port disabled");
     } else {
         // minijail_enter() will abort if any priv-dropping step fails.
diff --git a/adb/file_sync_service.cpp b/adb/file_sync_service.cpp
index 9a87931..1128993 100644
--- a/adb/file_sync_service.cpp
+++ b/adb/file_sync_service.cpp
@@ -48,10 +48,8 @@
 using android::base::StringPrintf;
 
 static bool should_use_fs_config(const std::string& path) {
-    // TODO: use fs_config to configure permissions on /data.
-    return android::base::StartsWith(path, "/system/") ||
-           android::base::StartsWith(path, "/vendor/") ||
-           android::base::StartsWith(path, "/oem/");
+    // TODO: use fs_config to configure permissions on /data too.
+    return !android::base::StartsWith(path, "/data/");
 }
 
 static bool update_capabilities(const char* path, uint64_t capabilities) {
diff --git a/adb/remount_service.cpp b/adb/remount_service.cpp
index a4c7a5a..d679a6d 100644
--- a/adb/remount_service.cpp
+++ b/adb/remount_service.cpp
@@ -145,8 +145,10 @@
     } else {
         success &= remount_partition(fd, "/system");
     }
-    success &= remount_partition(fd, "/vendor");
+    success &= remount_partition(fd, "/odm");
     success &= remount_partition(fd, "/oem");
+    success &= remount_partition(fd, "/product");
+    success &= remount_partition(fd, "/vendor");
 
     WriteFdExactly(fd, success ? "remount succeeded\n" : "remount failed\n");
 
diff --git a/healthd/Android.bp b/healthd/Android.bp
index c70278a..cefe09d 100644
--- a/healthd/Android.bp
+++ b/healthd/Android.bp
@@ -20,8 +20,8 @@
     export_header_lib_headers: ["libhealthd_headers"],
 }
 
-cc_binary {
-    name: "android.hardware.health@2.0-service",
+cc_defaults {
+    name: "android.hardware.health@2.0-service_defaults",
     init_rc: ["android.hardware.health@2.0-service.rc"],
     vendor: true,
     relative_install_path: "hw",
@@ -55,7 +55,22 @@
 }
 
 cc_binary {
+    name: "android.hardware.health@2.0-service",
+    defaults: ["android.hardware.health@2.0-service_defaults"],
+}
+
+cc_binary {
+    name: "android.hardware.health@2.0-service.override",
+    defaults: ["android.hardware.health@2.0-service_defaults"],
+
+    overrides: [
+        "healthd",
+    ],
+}
+
+cc_binary {
     name: "healthd",
+    init_rc: ["healthd.rc"],
     srcs: [
         "HealthServiceHealthd.cpp",
     ],
diff --git a/healthd/Android.mk b/healthd/Android.mk
index 7792eaf..818488d 100644
--- a/healthd/Android.mk
+++ b/healthd/Android.mk
@@ -100,7 +100,7 @@
     android.hardware.health@1.0-convert \
     libhidltransport \
     libhidlbase \
-    libhwbinder \
+    libhwbinder_noltopgo \
     libhealthstoragedefault \
     libvndksupport \
     libhealthd_charger \
diff --git a/healthd/android.hardware.health@2.0-service.rc b/healthd/android.hardware.health@2.0-service.rc
index 8b86868..dca0ccc 100644
--- a/healthd/android.hardware.health@2.0-service.rc
+++ b/healthd/android.hardware.health@2.0-service.rc
@@ -2,3 +2,4 @@
     class hal
     user system
     group system
+    file /dev/kmsg w
diff --git a/healthd/healthd.rc b/healthd/healthd.rc
new file mode 100644
index 0000000..8e2ebb6
--- /dev/null
+++ b/healthd/healthd.rc
@@ -0,0 +1,4 @@
+service healthd /system/bin/healthd
+    class hal
+    critical
+    group root system wakelock
diff --git a/init/stable_properties.h b/init/stable_properties.h
index b82f079..c2e2811 100644
--- a/init/stable_properties.h
+++ b/init/stable_properties.h
@@ -31,6 +31,7 @@
 static const std::set<std::string> kExportedActionableProperties = {
     "init.svc.console",
     "init.svc.mediadrm",
+    "init.svc.surfaceflinger",
     "init.svc.zygote",
     "persist.bluetooth.btsnoopenable",
     "persist.sys.crash_rcu",
@@ -51,6 +52,7 @@
     "sys.user.0.ce_available",
     "sys.vdso",
     "vts.native_server.on",
+    "wlan.driver.status",
 };
 
 }  // namespace init
diff --git a/libbacktrace/UnwindStackMap.cpp b/libbacktrace/UnwindStackMap.cpp
index 9c6fed4..d2d6ab8 100644
--- a/libbacktrace/UnwindStackMap.cpp
+++ b/libbacktrace/UnwindStackMap.cpp
@@ -149,13 +149,12 @@
   }
 
   // Create the process memory from the stack data.
-  uint64_t size = stack.end - stack.start;
-  unwindstack::MemoryBuffer* memory = new unwindstack::MemoryBuffer;
-  memory->Resize(size);
-  memcpy(memory->GetPtr(0), stack.data, size);
-  std::shared_ptr<unwindstack::Memory> shared_memory(memory);
-
-  process_memory_.reset(new unwindstack::MemoryRange(shared_memory, 0, size, stack.start));
+  if (memory_ == nullptr) {
+    memory_ = new unwindstack::MemoryOfflineBuffer(stack.data, stack.start, stack.end);
+    process_memory_.reset(memory_);
+  } else {
+    memory_->Reset(stack.data, stack.start, stack.end);
+  }
   return true;
 }
 
diff --git a/libbacktrace/UnwindStackMap.h b/libbacktrace/UnwindStackMap.h
index ec0d9c1..039f4a2 100644
--- a/libbacktrace/UnwindStackMap.h
+++ b/libbacktrace/UnwindStackMap.h
@@ -79,6 +79,9 @@
   bool Build(const std::vector<backtrace_map_t>& maps);
 
   bool CreateProcessMemory(const backtrace_stackinfo_t& stack);
+
+ private:
+  unwindstack::MemoryOfflineBuffer* memory_ = nullptr;
 };
 
 #endif  // _LIBBACKTRACE_UNWINDSTACK_MAP_H
diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp
index f6f7128..0f2b460 100644
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -122,6 +122,12 @@
     {odm_conf_file, odm_conf_dir},
 };
 
+// Do not use android_files to grant Linux capabilities.  Use ambient capabilities in their
+// associated init.rc file instead.  See https://source.android.com/devices/tech/config/ambient.
+
+// Do not place any new vendor/, data/vendor/, etc entries in android_files.
+// Vendor entries should be done via a vendor or device specific config.fs.
+// See https://source.android.com/devices/tech/config/filesystem#using-file-system-capabilities
 static const struct fs_path_config android_files[] = {
     // clang-format off
     { 00644, AID_SYSTEM,    AID_SYSTEM,    0, "data/app/*" },
@@ -185,24 +191,6 @@
     // Support FIFO scheduling mode in SurfaceFlinger.
     { 00755, AID_SYSTEM,    AID_GRAPHICS,  CAP_MASK_LONG(CAP_SYS_NICE),
                                               "system/bin/surfaceflinger" },
-
-    // Support hostapd administering a network interface.
-    { 00755, AID_WIFI,      AID_WIFI,      CAP_MASK_LONG(CAP_NET_ADMIN) |
-                                           CAP_MASK_LONG(CAP_NET_RAW),
-                                              "vendor/bin/hostapd" },
-
-    // Support Bluetooth legacy hal accessing /sys/class/rfkill
-    // Support RT scheduling in Bluetooth
-    { 00700, AID_BLUETOOTH, AID_BLUETOOTH, CAP_MASK_LONG(CAP_NET_ADMIN) |
-                                           CAP_MASK_LONG(CAP_SYS_NICE),
-                                              "vendor/bin/hw/android.hardware.bluetooth@1.0-service" },
-
-    // Support wifi_hal_legacy administering a network interface.
-    { 00755, AID_WIFI,      AID_WIFI,      CAP_MASK_LONG(CAP_NET_ADMIN) |
-                                           CAP_MASK_LONG(CAP_NET_RAW) |
-                                           CAP_MASK_LONG(CAP_SYS_MODULE),
-                                           "vendor/bin/hw/android.hardware.wifi@1.0-service" },
-
     // generic defaults
     { 00755, AID_ROOT,      AID_ROOT,      0, "bin/*" },
     { 00640, AID_ROOT,      AID_SHELL,     0, "fstab.*" },
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index ab01726..7b8111c 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -219,6 +219,7 @@
         "tests/MemoryFake.cpp",
         "tests/MemoryFileTest.cpp",
         "tests/MemoryLocalTest.cpp",
+        "tests/MemoryOfflineBufferTest.cpp",
         "tests/MemoryOfflineTest.cpp",
         "tests/MemoryRangeTest.cpp",
         "tests/MemoryRemoteTest.cpp",
diff --git a/libunwindstack/Memory.cpp b/libunwindstack/Memory.cpp
index d4ba680..beb2aad 100644
--- a/libunwindstack/Memory.cpp
+++ b/libunwindstack/Memory.cpp
@@ -345,6 +345,25 @@
   return memory_->Read(addr, dst, size);
 }
 
+MemoryOfflineBuffer::MemoryOfflineBuffer(const uint8_t* data, uint64_t start, uint64_t end)
+    : data_(data), start_(start), end_(end) {}
+
+void MemoryOfflineBuffer::Reset(const uint8_t* data, uint64_t start, uint64_t end) {
+  data_ = data;
+  start_ = start;
+  end_ = end;
+}
+
+size_t MemoryOfflineBuffer::Read(uint64_t addr, void* dst, size_t size) {
+  if (addr < start_ || addr >= end_) {
+    return 0;
+  }
+
+  size_t read_length = std::min(size, static_cast<size_t>(end_ - addr));
+  memcpy(dst, &data_[addr - start_], read_length);
+  return read_length;
+}
+
 MemoryOfflineParts::~MemoryOfflineParts() {
   for (auto memory : memories_) {
     delete memory;
diff --git a/libunwindstack/include/unwindstack/Memory.h b/libunwindstack/include/unwindstack/Memory.h
index 19bce04..c0c07f4 100644
--- a/libunwindstack/include/unwindstack/Memory.h
+++ b/libunwindstack/include/unwindstack/Memory.h
@@ -151,6 +151,21 @@
   std::unique_ptr<MemoryRange> memory_;
 };
 
+class MemoryOfflineBuffer : public Memory {
+ public:
+  MemoryOfflineBuffer(const uint8_t* data, uint64_t start, uint64_t end);
+  virtual ~MemoryOfflineBuffer() = default;
+
+  void Reset(const uint8_t* data, uint64_t start, uint64_t end);
+
+  size_t Read(uint64_t addr, void* dst, size_t size) override;
+
+ private:
+  const uint8_t* data_;
+  uint64_t start_;
+  uint64_t end_;
+};
+
 class MemoryOfflineParts : public Memory {
  public:
   MemoryOfflineParts() = default;
diff --git a/libunwindstack/tests/MemoryOfflineBufferTest.cpp b/libunwindstack/tests/MemoryOfflineBufferTest.cpp
new file mode 100644
index 0000000..f022884
--- /dev/null
+++ b/libunwindstack/tests/MemoryOfflineBufferTest.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vector>
+
+#include <gtest/gtest.h>
+
+#include <unwindstack/Memory.h>
+
+#include "LogFake.h"
+
+namespace unwindstack {
+
+class MemoryOfflineBufferTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    ResetLogs();
+    memory_.reset(new MemoryOfflineBuffer(buffer_.data(), kStart, kEnd));
+  }
+
+  static void SetUpTestCase() {
+    buffer_.resize(kLength);
+    for (size_t i = 0; i < kLength; i++) {
+      buffer_[i] = i % 189;
+    }
+  }
+
+  std::unique_ptr<MemoryOfflineBuffer> memory_;
+
+  static constexpr size_t kLength = 0x2000;
+  static constexpr uint64_t kStart = 0x1000;
+  static constexpr uint64_t kEnd = kStart + kLength;
+  static std::vector<uint8_t> buffer_;
+};
+
+std::vector<uint8_t> MemoryOfflineBufferTest::buffer_;
+
+static void VerifyBuffer(uint8_t* buffer, size_t start_value, size_t length) {
+  for (size_t i = 0; i < length; i++) {
+    ASSERT_EQ((start_value + i) % 189, buffer[i]) << "Failed at byte " << i;
+  }
+}
+
+TEST_F(MemoryOfflineBufferTest, read_out_of_bounds) {
+  std::vector<uint8_t> buffer(1024);
+  ASSERT_FALSE(memory_->ReadFully(0, buffer.data(), 1));
+  ASSERT_FALSE(memory_->ReadFully(0xfff, buffer.data(), 1));
+  ASSERT_FALSE(memory_->ReadFully(0xfff, buffer.data(), 2));
+  ASSERT_FALSE(memory_->ReadFully(0x3000, buffer.data(), 1));
+  ASSERT_FALSE(memory_->ReadFully(0x3001, buffer.data(), 1));
+}
+
+TEST_F(MemoryOfflineBufferTest, read) {
+  std::vector<uint8_t> buffer(1024);
+  ASSERT_TRUE(memory_->ReadFully(kStart, buffer.data(), 10));
+  ASSERT_NO_FATAL_FAILURE(VerifyBuffer(buffer.data(), 0, 10));
+
+  ASSERT_TRUE(memory_->ReadFully(kStart + 555, buffer.data(), 40));
+  ASSERT_NO_FATAL_FAILURE(VerifyBuffer(buffer.data(), 555, 40));
+
+  ASSERT_TRUE(memory_->ReadFully(kStart + kLength - 105, buffer.data(), 105));
+  ASSERT_NO_FATAL_FAILURE(VerifyBuffer(buffer.data(), kLength - 105, 105));
+}
+
+TEST_F(MemoryOfflineBufferTest, read_past_end) {
+  std::vector<uint8_t> buffer(1024);
+  ASSERT_EQ(100U, memory_->Read(kStart + kLength - 100, buffer.data(), buffer.size()));
+  VerifyBuffer(buffer.data(), kLength - 100, 100);
+}
+
+TEST_F(MemoryOfflineBufferTest, read_after_reset) {
+  std::vector<uint8_t> buffer(1024);
+  ASSERT_TRUE(memory_->ReadFully(kStart, buffer.data(), 100));
+  ASSERT_NO_FATAL_FAILURE(VerifyBuffer(buffer.data(), 0, 100));
+
+  memory_->Reset(&buffer_[10], 0x12000, 0x13000);
+  ASSERT_TRUE(memory_->ReadFully(0x12000, buffer.data(), 100));
+  ASSERT_NO_FATAL_FAILURE(VerifyBuffer(buffer.data(), 10, 100));
+
+  ASSERT_EQ(50U, memory_->Read(0x13000 - 50, buffer.data(), buffer.size()));
+  ASSERT_NO_FATAL_FAILURE(VerifyBuffer(buffer.data(), 0x1000 - 50 + 10, 50));
+}
+
+}  // namespace unwindstack
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index a78319f..9b04363 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -1115,9 +1115,6 @@
         // client wants to start from the beginning
         it = mLogElements.begin();
     } else {
-        // 3 second limit to continue search for out-of-order entries.
-        log_time min = start - pruneMargin;
-
         // Cap to 300 iterations we look back for out-of-order entries.
         size_t count = 300;
 
@@ -1133,7 +1130,7 @@
             } else if (element->getRealTime() == start) {
                 last = ++it;
                 break;
-            } else if (!--count || (element->getRealTime() < min)) {
+            } else if (!--count) {
                 break;
             }
         }
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 3bbc506..391f42a 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -736,11 +736,6 @@
     seclabel u:r:ueventd:s0
     shutdown critical
 
-service healthd /system/bin/healthd
-    class hal
-    critical
-    group root system wakelock
-
 service console /system/bin/sh
     class core
     console