Merge "dmctl: add repalce command to usage list"
diff --git a/debuggerd/client/debuggerd_client.cpp b/debuggerd/client/debuggerd_client.cpp
index b302918..c9e097e 100644
--- a/debuggerd/client/debuggerd_client.cpp
+++ b/debuggerd/client/debuggerd_client.cpp
@@ -216,7 +216,7 @@
       log_error(output_fd, 0,
                 "received packet of unexpected length from tombstoned while reading %s response: "
                 "expected %zd, received %zd",
-                kind, sizeof(response), rc);
+                kind, sizeof(*response), rc);
       return false;
     }
     return true;
diff --git a/debuggerd/crasher/crasher.cpp b/debuggerd/crasher/crasher.cpp
index 4043a6e..6a19878 100644
--- a/debuggerd/crasher/crasher.cpp
+++ b/debuggerd/crasher/crasher.cpp
@@ -164,7 +164,8 @@
 }
 
 noinline void readdir_null() {
-    readdir(nullptr);
+    DIR* sneaky_null = nullptr;
+    readdir(sneaky_null);
 }
 
 noinline int strlen_null() {
diff --git a/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp b/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
index e4d68f8..8e6abdf 100644
--- a/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
+++ b/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
@@ -190,6 +190,7 @@
 static void print_thread_backtrace(CallbackType callback, const Tombstone& tombstone,
                                    const Thread& thread, bool should_log) {
   CBS("");
+  CB(should_log, "%d total frames", thread.current_backtrace().size());
   CB(should_log, "backtrace:");
   if (!thread.backtrace_note().empty()) {
     CB(should_log, "  NOTE: %s",
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index b977e31..d7d2091 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -1560,10 +1560,10 @@
     }
 }
 
-std::string GetPartitionName(const ImageEntry& entry) {
+std::string GetPartitionName(const ImageEntry& entry, std::string& current_slot) {
     auto slot = entry.second;
     if (slot.empty()) {
-        slot = get_current_slot();
+        slot = current_slot;
     }
     if (slot.empty()) {
         return entry.first->part_name;
@@ -1582,7 +1582,7 @@
 
   private:
     void CheckRequirements();
-    void DetermineSecondarySlot();
+    void DetermineSlot();
     void CollectImages();
     void FlashImages(const std::vector<std::pair<const Image*, std::string>>& images);
     void FlashImage(const Image& image, const std::string& slot, fastboot_buffer* buf);
@@ -1606,7 +1606,9 @@
         set_active(fp_->slot_override);
     }
 
-    DetermineSecondarySlot();
+    DetermineSlot();
+    CollectImages();
+
     CancelSnapshotIfNeeded();
 
     // First flash boot partitions. We allow this to happen either in userspace
@@ -1651,7 +1653,13 @@
     ::CheckRequirements({contents.data(), contents.size()}, fp_->force_flash);
 }
 
-void FlashAllTool::DetermineSecondarySlot() {
+void FlashAllTool::DetermineSlot() {
+    if (fp_->slot_override.empty()) {
+        fp_->current_slot = get_current_slot();
+    } else {
+        fp_->current_slot = fp_->slot_override;
+    }
+
     if (fp_->skip_secondary) {
         return;
     }
@@ -2009,7 +2017,6 @@
     std::unique_ptr<FlashingPlan> fp = std::make_unique<FlashingPlan>();
 
     int longindex;
-    std::string slot_override;
     std::string next_active;
 
     g_boot_img_hdr.kernel_addr = 0x00008000;
@@ -2082,7 +2089,7 @@
             } else if (name == "skip-secondary") {
                 fp->skip_secondary = true;
             } else if (name == "slot") {
-                slot_override = optarg;
+                fp->slot_override = optarg;
             } else if (name == "dtb-offset") {
                 g_boot_img_hdr.dtb_addr = strtoul(optarg, 0, 16);
             } else if (name == "tags-offset") {
@@ -2174,12 +2181,12 @@
 
     const double start = now();
 
-    if (slot_override != "") slot_override = verify_slot(slot_override);
+    if (fp->slot_override != "") fp->slot_override = verify_slot(fp->slot_override);
     if (next_active != "") next_active = verify_slot(next_active, false);
 
     if (fp->wants_set_active) {
         if (next_active == "") {
-            if (slot_override == "") {
+            if (fp->slot_override == "") {
                 std::string current_slot;
                 if (fb->GetVar("current-slot", &current_slot) == fastboot::SUCCESS) {
                     if (current_slot[0] == '_') current_slot.erase(0, 1);
@@ -2188,7 +2195,7 @@
                     fp->wants_set_active = false;
                 }
             } else {
-                next_active = verify_slot(slot_override, false);
+                next_active = verify_slot(fp->slot_override, false);
             }
         }
     }
@@ -2213,7 +2220,7 @@
 
                 fb->Erase(partition);
             };
-            do_for_partitions(partition, slot_override, erase, true);
+            do_for_partitions(partition, fp->slot_override, erase, true);
         } else if (android::base::StartsWith(command, "format")) {
             // Parsing for: "format[:[type][:[size]]]"
             // Some valid things:
@@ -2233,7 +2240,7 @@
             auto format = [&](const std::string& partition) {
                 fb_perform_format(partition, 0, type_override, size_override, fp->fs_options);
             };
-            do_for_partitions(partition, slot_override, format, true);
+            do_for_partitions(partition, fp->slot_override, format, true);
         } else if (command == "signature") {
             std::string filename = next_arg(&args);
             std::vector<char> data;
@@ -2247,7 +2254,7 @@
             if (args.size() == 1) {
                 std::string reboot_target = next_arg(&args);
                 reboot_task = std::make_unique<RebootTask>(fp.get(), reboot_target);
-            } else {
+            } else if (!fp->skip_reboot) {
                 reboot_task = std::make_unique<RebootTask>(fp.get());
             }
             if (!args.empty()) syntax_error("junk after reboot command");
@@ -2278,7 +2285,7 @@
             }
             if (fname.empty()) die("cannot determine image filename for '%s'", pname.c_str());
 
-            FlashTask task(slot_override, pname, fname, is_vbmeta_partition(pname));
+            FlashTask task(fp->slot_override, pname, fname, is_vbmeta_partition(pname));
             task.Run();
         } else if (command == "flash:raw") {
             std::string partition = next_arg(&args);
@@ -2292,9 +2299,9 @@
             auto flashraw = [&data](const std::string& partition) {
                 fb->FlashPartition(partition, data);
             };
-            do_for_partitions(partition, slot_override, flashraw, true);
+            do_for_partitions(partition, fp->slot_override, flashraw, true);
         } else if (command == "flashall") {
-            if (slot_override == "all") {
+            if (fp->slot_override == "all") {
                 fprintf(stderr,
                         "Warning: slot set to 'all'. Secondary slots will not be flashed.\n");
                 fp->skip_secondary = true;
@@ -2302,9 +2309,11 @@
             } else {
                 do_flashall(fp.get());
             }
-            reboot_task = std::make_unique<RebootTask>(fp.get());
+            if (!fp->skip_reboot) {
+                reboot_task = std::make_unique<RebootTask>(fp.get());
+            }
         } else if (command == "update") {
-            bool slot_all = (slot_override == "all");
+            bool slot_all = (fp->slot_override == "all");
             if (slot_all) {
                 fprintf(stderr,
                         "Warning: slot set to 'all'. Secondary slots will not be flashed.\n");
@@ -2314,7 +2323,9 @@
                 filename = next_arg(&args);
             }
             do_update(filename.c_str(), fp.get());
-            reboot_task = std::make_unique<RebootTask>(fp.get());
+            if (!fp->skip_reboot) {
+                reboot_task = std::make_unique<RebootTask>(fp.get());
+            }
         } else if (command == FB_CMD_SET_ACTIVE) {
             std::string slot = verify_slot(next_arg(&args), false);
             fb->SetActive(slot);
@@ -2353,7 +2364,7 @@
             std::string partition = next_arg(&args);
             std::string size = next_arg(&args);
             std::unique_ptr<ResizeTask> resize_task =
-                    std::make_unique<ResizeTask>(fp.get(), partition, size, slot_override);
+                    std::make_unique<ResizeTask>(fp.get(), partition, size, fp->slot_override);
             resize_task->Run();
         } else if (command == "gsi") {
             std::string arg = next_arg(&args);
@@ -2371,7 +2382,7 @@
             } else {
                 image = next_arg(&args);
             }
-            do_wipe_super(image, slot_override);
+            do_wipe_super(image, fp->slot_override);
         } else if (command == "snapshot-update") {
             std::string arg;
             if (!args.empty()) {
@@ -2384,7 +2395,7 @@
         } else if (command == FB_CMD_FETCH) {
             std::string partition = next_arg(&args);
             std::string outfile = next_arg(&args);
-            do_fetch(partition, slot_override, outfile);
+            do_fetch(partition, fp->slot_override, outfile);
         } else {
             syntax_error("unknown command %s", command.c_str());
         }
@@ -2403,7 +2414,7 @@
     if (fp->wants_set_active) {
         fb->SetActive(next_active);
     }
-    if (reboot_task && !fp->skip_reboot) {
+    if (reboot_task) {
         reboot_task->Run();
     }
     fprintf(stderr, "Finished. Total time: %.3fs\n", (now() - start));
diff --git a/fastboot/fastboot.h b/fastboot/fastboot.h
index 029b583..6462a4f 100644
--- a/fastboot/fastboot.h
+++ b/fastboot/fastboot.h
@@ -81,6 +81,7 @@
     bool force_flash = false;
 
     std::string slot_override;
+    std::string current_slot;
     std::string secondary_slot;
     fastboot::FastBootDriver* fb;
 };
@@ -102,7 +103,7 @@
 
 Result<NetworkSerial, FastbootError> ParseNetworkSerial(const std::string& serial);
 bool supports_AB();
-std::string GetPartitionName(const ImageEntry& entry);
+std::string GetPartitionName(const ImageEntry& entry, std::string& current_slot_);
 void flash_partition_files(const std::string& partition, const std::vector<SparsePtr>& files);
 int64_t get_sparse_limit(int64_t size);
 std::vector<SparsePtr> resparse_file(sparse_file* s, int64_t max_size);
diff --git a/fastboot/task.cpp b/fastboot/task.cpp
index 3d2c975..de48a16 100644
--- a/fastboot/task.cpp
+++ b/fastboot/task.cpp
@@ -42,8 +42,8 @@
     do_for_partitions(pname_, slot_, flash, true);
 }
 
-RebootTask::RebootTask(FlashingPlan* fp) : fp_(fp){};
-RebootTask::RebootTask(FlashingPlan* fp, const std::string& reboot_target)
+RebootTask::RebootTask(const FlashingPlan* fp) : fp_(fp){};
+RebootTask::RebootTask(const FlashingPlan* fp, const std::string& reboot_target)
     : reboot_target_(reboot_target), fp_(fp){};
 
 void RebootTask::Run() {
@@ -132,7 +132,7 @@
     }
 
     for (const auto& entry : os_images) {
-        auto partition = GetPartitionName(entry);
+        auto partition = GetPartitionName(entry, fp->current_slot);
         auto image = entry.first;
 
         if (!helper->AddPartition(partition, image->img_name, image->optional_if_no_image)) {
@@ -145,7 +145,7 @@
 
     // Remove images that we already flashed, just in case we have non-dynamic OS images.
     auto remove_if_callback = [&](const ImageEntry& entry) -> bool {
-        return helper->WillFlash(GetPartitionName(entry));
+        return helper->WillFlash(GetPartitionName(entry, fp->current_slot));
     };
     os_images.erase(std::remove_if(os_images.begin(), os_images.end(), remove_if_callback),
                     os_images.end());
@@ -153,7 +153,7 @@
                                                   partition_size);
 }
 
-UpdateSuperTask::UpdateSuperTask(FlashingPlan* fp) : fp_(fp) {}
+UpdateSuperTask::UpdateSuperTask(const FlashingPlan* fp) : fp_(fp) {}
 
 void UpdateSuperTask::Run() {
     unique_fd fd = fp_->source->OpenFile("super_empty.img");
@@ -177,7 +177,7 @@
     fp_->fb->RawCommand(command, "Updating super partition");
 }
 
-ResizeTask::ResizeTask(FlashingPlan* fp, const std::string& pname, const std::string& size,
+ResizeTask::ResizeTask(const FlashingPlan* fp, const std::string& pname, const std::string& size,
                        const std::string& slot)
     : fp_(fp), pname_(pname), size_(size), slot_(slot) {}
 
@@ -190,13 +190,13 @@
     do_for_partitions(pname_, slot_, resize_partition, false);
 }
 
-DeleteTask::DeleteTask(FlashingPlan* fp, const std::string& pname) : fp_(fp), pname_(pname){};
+DeleteTask::DeleteTask(const FlashingPlan* fp, const std::string& pname) : fp_(fp), pname_(pname){};
 
 void DeleteTask::Run() {
     fp_->fb->DeletePartition(pname_);
 }
 
-WipeTask::WipeTask(FlashingPlan* fp, const std::string& pname) : fp_(fp), pname_(pname){};
+WipeTask::WipeTask(const FlashingPlan* fp, const std::string& pname) : fp_(fp), pname_(pname){};
 
 void WipeTask::Run() {
     std::string partition_type;
diff --git a/fastboot/task.h b/fastboot/task.h
index e89f85b..e80f88d 100644
--- a/fastboot/task.h
+++ b/fastboot/task.h
@@ -46,8 +46,8 @@
 
 class RebootTask : public Task {
   public:
-    RebootTask(FlashingPlan* fp);
-    RebootTask(FlashingPlan* fp, const std::string& reboot_target);
+    RebootTask(const FlashingPlan* fp);
+    RebootTask(const FlashingPlan* fp, const std::string& reboot_target);
     void Run() override;
 
   private:
@@ -73,7 +73,7 @@
 
 class UpdateSuperTask : public Task {
   public:
-    UpdateSuperTask(FlashingPlan* fp);
+    UpdateSuperTask(const FlashingPlan* fp);
     void Run() override;
 
   private:
@@ -82,7 +82,7 @@
 
 class ResizeTask : public Task {
   public:
-    ResizeTask(FlashingPlan* fp, const std::string& pname, const std::string& size,
+    ResizeTask(const FlashingPlan* fp, const std::string& pname, const std::string& size,
                const std::string& slot);
     void Run() override;
 
@@ -95,7 +95,7 @@
 
 class DeleteTask : public Task {
   public:
-    DeleteTask(FlashingPlan* _fp, const std::string& _pname);
+    DeleteTask(const FlashingPlan* _fp, const std::string& _pname);
     void Run() override;
 
   private:
@@ -105,7 +105,7 @@
 
 class WipeTask : public Task {
   public:
-    WipeTask(FlashingPlan* fp, const std::string& pname);
+    WipeTask(const FlashingPlan* fp, const std::string& pname);
     void Run() override;
 
   private:
diff --git a/init/README.md b/init/README.md
index b006365..6bdff4a 100644
--- a/init/README.md
+++ b/init/README.md
@@ -642,17 +642,17 @@
   the current SELinux policy or its parent if not specified in the policy. If
   the directory exists, its security context will not be changed (even if
   different from the policy).
-
-  > _action_ can be one of:
-  * `None`: take no encryption action; directory will be encrypted if parent is.
-  * `Require`: encrypt directory, abort boot process if encryption fails
-  * `Attempt`: try to set an encryption policy, but continue if it fails
-  * `DeleteIfNecessary`: recursively delete directory if necessary to set
-  encryption policy.
-
-  > _key_ can be one of:
-  * `ref`: use the systemwide DE key
-  * `per_boot_ref`: use the key freshly generated on each boot.
+>
+> _action_ can be one of:
+>  * `None`: take no encryption action; directory will be encrypted if parent is.
+>  * `Require`: encrypt directory, abort boot process if encryption fails
+>  * `Attempt`: try to set an encryption policy, but continue if it fails
+>  * `DeleteIfNecessary`: recursively delete directory if necessary to set
+>  encryption policy.
+>
+> _key_ can be one of:
+>  * `ref`: use the systemwide DE key
+>  * `per_boot_ref`: use the key freshly generated on each boot.
 
 `mount_all [ <fstab> ] [--<option>]`
 > Calls fs\_mgr\_mount\_all on the given fs\_mgr-format fstab with optional
diff --git a/init/init_test.cpp b/init/init_test.cpp
index 305bf95..0fc3ffc 100644
--- a/init/init_test.cpp
+++ b/init/init_test.cpp
@@ -204,6 +204,10 @@
         GTEST_SKIP() << "Must run on userdebug/eng builds. b/262090304";
         return;
     }
+    if (getuid() != 0) {
+        GTEST_SKIP() << "Must be run as root.";
+        return;
+    }
     std::string init_script = R"init(
 service console /system/bin/sh
     class core
diff --git a/init/selinux.cpp b/init/selinux.cpp
index 062ed39..907eb80 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -761,15 +761,7 @@
 
 constexpr size_t kKlogMessageSize = 1024;
 
-void SelinuxAvcLog(char* buf, size_t buf_len) {
-    CHECK_GT(buf_len, 0u);
-
-    size_t str_len = strnlen(buf, buf_len);
-    // trim newline at end of string
-    if (buf[str_len - 1] == '\n') {
-        buf[str_len - 1] = '\0';
-    }
-
+void SelinuxAvcLog(char* buf) {
     struct NetlinkMessage {
         nlmsghdr hdr;
         char buf[kKlogMessageSize];
@@ -835,8 +827,17 @@
     if (length_written <= 0) {
         return 0;
     }
+
+    // libselinux log messages usually contain a new line character, while
+    // Android LOG() does not expect it. Remove it to avoid empty lines in
+    // the log buffers.
+    size_t str_len = strlen(buf);
+    if (buf[str_len - 1] == '\n') {
+        buf[str_len - 1] = '\0';
+    }
+
     if (type == SELINUX_AVC) {
-        SelinuxAvcLog(buf, sizeof(buf));
+        SelinuxAvcLog(buf);
     } else {
         android::base::KernelLogger(android::base::MAIN, severity, "selinux", nullptr, 0, buf);
     }
diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp
index a6835fc..e46774b 100644
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -83,6 +83,8 @@
     { 00751, AID_ROOT,         AID_SHELL,        0, "product/apex/*/bin" },
     { 00777, AID_ROOT,         AID_ROOT,         0, "sdcard" },
     { 00751, AID_ROOT,         AID_SDCARD_R,     0, "storage" },
+    { 00750, AID_ROOT,         AID_SYSTEM,       0, "system/apex/com.android.tethering/bin/for-system" },
+    { 00750, AID_ROOT,         AID_SYSTEM,       0, "system/apex/com.android.tethering.inprocess/bin/for-system" },
     { 00751, AID_ROOT,         AID_SHELL,        0, "system/bin" },
     { 00755, AID_ROOT,         AID_ROOT,         0, "system/etc/ppp" },
     { 00755, AID_ROOT,         AID_SHELL,        0, "system/vendor" },
@@ -194,6 +196,8 @@
 
     // the following files have enhanced capabilities and ARE included
     // in user builds.
+    { 06755, AID_CLAT,      AID_CLAT,      0, "system/apex/com.android.tethering/bin/for-system/clatd" },
+    { 06755, AID_CLAT,      AID_CLAT,      0, "system/apex/com.android.tethering.inprocess/bin/for-system/clatd" },
     { 00700, AID_SYSTEM,    AID_SHELL,     CAP_MASK_LONG(CAP_BLOCK_SUSPEND),
                                               "system/bin/inputflinger" },
     { 00750, AID_ROOT,      AID_SHELL,     CAP_MASK_LONG(CAP_SETUID) |
diff --git a/libmodprobe/Android.bp b/libmodprobe/Android.bp
index 525a880..1d94a96 100644
--- a/libmodprobe/Android.bp
+++ b/libmodprobe/Android.bp
@@ -10,6 +10,7 @@
     vendor_available: true,
     ramdisk_available: true,
     recovery_available: true,
+    host_supported: true,
     srcs: [
         "libmodprobe.cpp",
         "libmodprobe_ext.cpp",
diff --git a/libprocessgroup/task_profiles_test.cpp b/libprocessgroup/task_profiles_test.cpp
index 09ac44c..c449e95 100644
--- a/libprocessgroup/task_profiles_test.cpp
+++ b/libprocessgroup/task_profiles_test.cpp
@@ -43,7 +43,7 @@
     }
     struct mntent* mnt;
     while ((mnt = getmntent(mnts.get()))) {
-        if (strcmp(mnt->mnt_fsname, "cgroup2") == 0) {
+        if (strcmp(mnt->mnt_type, "cgroup2") == 0) {
             return true;
         }
     }