Merge changes from topic "merge_set-verity-state_with_remount"

* changes:
  remount: Merge 'remount' and 'set-verity-state'
  remount: Use MyLogger class and sundry improvements
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 5468fb8..bb24abf 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -69,6 +69,7 @@
 namespace {
 
 constexpr char kDataScratchSizeMbProp[] = "fs_mgr.overlayfs.data_scratch_size_mb";
+constexpr char kPreferCacheBackingStorageProp[] = "fs_mgr.overlayfs.prefer_cache_backing_storage";
 
 bool fs_mgr_access(const std::string& path) {
     return access(path.c_str(), F_OK) == 0;
@@ -101,6 +102,10 @@
 const auto kScratchMountPoint = "/mnt/scratch"s;
 const auto kCacheMountPoint = "/cache"s;
 
+bool IsABDevice() {
+    return !android::base::GetProperty("ro.boot.slot_suffix", "").empty();
+}
+
 std::vector<const std::string> OverlayMountPoints() {
     // Never fallback to legacy cache mount point if within a DSU system,
     // because running a DSU system implies the device supports dynamic
@@ -108,6 +113,15 @@
     if (fs_mgr_is_dsu_running()) {
         return {kScratchMountPoint};
     }
+
+    // For non-A/B devices prefer cache backing storage if
+    // kPreferCacheBackingStorageProp property set.
+    if (!IsABDevice() &&
+        android::base::GetBoolProperty(kPreferCacheBackingStorageProp, false) &&
+        android::base::GetIntProperty("ro.vendor.api_level", -1) < __ANDROID_API_T__) {
+        return {kCacheMountPoint, kScratchMountPoint};
+    }
+
     return {kScratchMountPoint, kCacheMountPoint};
 }
 
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h
index b93fd32..a9682a1 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h
@@ -16,6 +16,7 @@
 
 #include <stdint.h>
 
+#include <cstdint>
 #include <memory>
 #include <optional>
 #include <string>
@@ -150,6 +151,7 @@
     bool SetFd(android::base::borrowed_fd fd);
     bool Sync();
     bool Truncate(off_t length);
+    bool EnsureSpaceAvailable(const uint64_t bytes_needed) const;
 
   private:
     android::base::unique_fd owned_fd_;
@@ -165,6 +167,7 @@
     bool is_dev_null_ = false;
     bool merge_in_progress_ = false;
     bool is_block_device_ = false;
+    uint64_t cow_image_size_ = INT64_MAX;
 };
 
 }  // namespace snapshot
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/cow_compress.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/cow_compress.cpp
index e58f45a..0eb231b 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/cow_compress.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/cow_compress.cpp
@@ -84,7 +84,13 @@
                            << ", compression bound: " << bound << ", ret: " << compressed_size;
                 return {};
             }
-            buffer.resize(compressed_size);
+            // Don't run compression if the compressed output is larger
+            if (compressed_size >= length) {
+                buffer.resize(length);
+                memcpy(buffer.data(), data, length);
+            } else {
+                buffer.resize(compressed_size);
+            }
             return buffer;
         }
         default:
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/cow_decompress.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/cow_decompress.cpp
index a4d2277..139a29f 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/cow_decompress.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/cow_decompress.cpp
@@ -273,6 +273,18 @@
                        << actual_buffer_size << " bytes";
             return false;
         }
+        // If input size is same as output size, then input is uncompressed.
+        if (stream_->Size() == output_size) {
+            size_t bytes_read = 0;
+            stream_->Read(output_buffer, output_size, &bytes_read);
+            if (bytes_read != output_size) {
+                LOG(ERROR) << "Failed to read all input at once. Expected: " << output_size
+                           << " actual: " << bytes_read;
+                return false;
+            }
+            sink_->ReturnData(output_buffer, output_size);
+            return true;
+        }
         std::string input_buffer;
         input_buffer.resize(stream_->Size());
         size_t bytes_read = 0;
diff --git a/fs_mgr/libsnapshot/libsnapshot_cow/cow_writer.cpp b/fs_mgr/libsnapshot/libsnapshot_cow/cow_writer.cpp
index 5f5d1fb..43c17a6 100644
--- a/fs_mgr/libsnapshot/libsnapshot_cow/cow_writer.cpp
+++ b/fs_mgr/libsnapshot/libsnapshot_cow/cow_writer.cpp
@@ -30,9 +30,29 @@
 #include <lz4.h>
 #include <zlib.h>
 
+#include <fcntl.h>
+#include <linux/fs.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
 namespace android {
 namespace snapshot {
 
+namespace {
+std::string GetFdPath(int fd) {
+    const auto fd_path = "/proc/self/fd/" + std::to_string(fd);
+    std::string file_path(512, '\0');
+    const auto err = readlink(fd_path.c_str(), file_path.data(), file_path.size());
+    if (err <= 0) {
+        PLOG(ERROR) << "Failed to determine path for fd " << fd;
+        file_path.clear();
+    } else {
+        file_path.resize(err);
+    }
+    return file_path;
+}
+}  // namespace
+
 static_assert(sizeof(off_t) == sizeof(uint64_t));
 
 using android::base::borrowed_fd;
@@ -163,12 +183,25 @@
     } else {
         fd_ = fd;
 
-        struct stat stat;
+        struct stat stat {};
         if (fstat(fd.get(), &stat) < 0) {
             PLOG(ERROR) << "fstat failed";
             return false;
         }
+        const auto file_path = GetFdPath(fd.get());
         is_block_device_ = S_ISBLK(stat.st_mode);
+        if (is_block_device_) {
+            uint64_t size_in_bytes = 0;
+            if (ioctl(fd.get(), BLKGETSIZE64, &size_in_bytes)) {
+                PLOG(ERROR) << "Failed to get total size for: " << fd.get();
+                return false;
+            }
+            cow_image_size_ = size_in_bytes;
+            LOG(INFO) << "COW image " << file_path << " has size " << size_in_bytes;
+        } else {
+            LOG(INFO) << "COW image " << file_path
+                      << " is not a block device, assuming unlimited space.";
+        }
     }
     return true;
 }
@@ -343,7 +376,8 @@
             op.data_length = static_cast<uint16_t>(data.size());
 
             if (!WriteOperation(op, data.data(), data.size())) {
-                PLOG(ERROR) << "AddRawBlocks: write failed";
+                PLOG(ERROR) << "AddRawBlocks: write failed, bytes requested: " << size
+                            << ", bytes written: " << i * header_.block_size;
                 return false;
             }
         } else {
@@ -512,12 +546,26 @@
     return true;
 }
 
-bool CowWriter::WriteOperation(const CowOperation& op, const void* data, size_t size) {
-    if (lseek(fd_.get(), next_op_pos_, SEEK_SET) < 0) {
-        PLOG(ERROR) << "lseek failed for writing operation.";
+bool CowWriter::EnsureSpaceAvailable(const uint64_t bytes_needed) const {
+    if (bytes_needed > cow_image_size_) {
+        LOG(ERROR) << "No space left on COW device. Required: " << bytes_needed
+                   << ", available: " << cow_image_size_;
+        errno = ENOSPC;
         return false;
     }
-    if (!android::base::WriteFully(fd_, reinterpret_cast<const uint8_t*>(&op), sizeof(op))) {
+    return true;
+}
+
+bool CowWriter::WriteOperation(const CowOperation& op, const void* data, size_t size) {
+    if (!EnsureSpaceAvailable(next_op_pos_ + sizeof(op))) {
+        return false;
+    }
+    if (!EnsureSpaceAvailable(next_data_pos_ + size)) {
+        return false;
+    }
+
+    if (!android::base::WriteFullyAtOffset(fd_, reinterpret_cast<const uint8_t*>(&op), sizeof(op),
+                                           next_op_pos_)) {
         return false;
     }
     if (data != nullptr && size > 0) {
@@ -542,13 +590,8 @@
     next_op_pos_ += sizeof(CowOperation) + GetNextOpOffset(op, header_.cluster_ops);
 }
 
-bool CowWriter::WriteRawData(const void* data, size_t size) {
-    if (lseek(fd_.get(), next_data_pos_, SEEK_SET) < 0) {
-        PLOG(ERROR) << "lseek failed for writing data.";
-        return false;
-    }
-
-    if (!android::base::WriteFully(fd_, data, size)) {
+bool CowWriter::WriteRawData(const void* data, const size_t size) {
+    if (!android::base::WriteFullyAtOffset(fd_, data, size, next_data_pos_)) {
         return false;
     }
     return true;
diff --git a/fs_mgr/libsnapshot/utility.cpp b/fs_mgr/libsnapshot/utility.cpp
index cadd24d..a98bf0e 100644
--- a/fs_mgr/libsnapshot/utility.cpp
+++ b/fs_mgr/libsnapshot/utility.cpp
@@ -17,6 +17,7 @@
 #include <errno.h>
 #include <time.h>
 
+#include <filesystem>
 #include <iomanip>
 #include <sstream>
 
@@ -152,6 +153,24 @@
     }
 }
 
+bool FsyncDirectory(const char* dirname) {
+    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(dirname, O_RDONLY | O_CLOEXEC)));
+    if (fd == -1) {
+        PLOG(ERROR) << "Failed to open " << dirname;
+        return false;
+    }
+    if (fsync(fd) == -1) {
+        if (errno == EROFS || errno == EINVAL) {
+            PLOG(WARNING) << "Skip fsync " << dirname
+                          << " on a file system does not support synchronization";
+        } else {
+            PLOG(ERROR) << "Failed to fsync " << dirname;
+            return false;
+        }
+    }
+    return true;
+}
+
 bool WriteStringToFileAtomic(const std::string& content, const std::string& path) {
     const std::string tmp_path = path + ".tmp";
     {
@@ -175,11 +194,11 @@
         PLOG(ERROR) << "rename failed from " << tmp_path << " to " << path;
         return false;
     }
-    return true;
+    return FsyncDirectory(std::filesystem::path(path).parent_path().c_str());
 }
 
 std::ostream& operator<<(std::ostream& os, const Now&) {
-    struct tm now;
+    struct tm now {};
     time_t t = time(nullptr);
     localtime_r(&t, &now);
     return os << std::put_time(&now, "%Y%m%d-%H%M%S");
diff --git a/fs_mgr/libsnapshot/utility.h b/fs_mgr/libsnapshot/utility.h
index eff6f10..8c4c7c6 100644
--- a/fs_mgr/libsnapshot/utility.h
+++ b/fs_mgr/libsnapshot/utility.h
@@ -117,6 +117,7 @@
 // Note that rename() is an atomic operation. This function may not work properly if there
 // is an open fd to |path|, because that fd has an old view of the file.
 bool WriteStringToFileAtomic(const std::string& content, const std::string& path);
+bool FsyncDirectory(const char* dirname);
 
 // Writes current time to a given stream.
 struct Now {};
diff --git a/init/init.cpp b/init/init.cpp
index 57397b5..540e2ca 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -513,7 +513,7 @@
 }
 
 static Result<void> DoLoadApex(const std::string& apex_name) {
-    if(auto result = ParseApexConfigs(apex_name); !result.ok()) {
+    if (auto result = ParseApexConfigs(apex_name); !result.ok()) {
         return result.error();
     }
 
diff --git a/init/service.cpp b/init/service.cpp
index caa9095..c260c07 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -506,8 +506,7 @@
 }
 
 // Enters namespaces, sets environment variables, writes PID files and runs the service executable.
-void Service::RunService(const std::vector<Descriptor>& descriptors,
-                         InterprocessFifo cgroups_activated, InterprocessFifo setsid_finished) {
+void Service::RunService(const std::vector<Descriptor>& descriptors, InterprocessFifo fifo) {
     if (auto result = EnterNamespaces(namespaces_, name_, mount_namespace_); !result.ok()) {
         LOG(FATAL) << "Service '" << name_ << "' failed to set up namespaces: " << result.error();
     }
@@ -529,11 +528,11 @@
 
     // Wait until the cgroups have been created and until the cgroup controllers have been
     // activated.
-    Result<uint8_t> byte = cgroups_activated.Read();
+    Result<uint8_t> byte = fifo.Read();
     if (!byte.ok()) {
         LOG(ERROR) << name_ << ": failed to read from notification channel: " << byte.error();
     }
-    cgroups_activated.Close();
+    fifo.Close();
     if (!*byte) {
         LOG(FATAL) << "Service '" << name_  << "' failed to start due to a fatal error";
         _exit(EXIT_FAILURE);
@@ -557,12 +556,6 @@
     // priority. Aborts on failure.
     SetProcessAttributesAndCaps();
 
-    // If SetProcessAttributes() called setsid(), report this to the parent.
-    if (!proc_attr_.console.empty()) {
-        setsid_finished.Write(2);
-    }
-    setsid_finished.Close();
-
     if (!ExpandArgsAndExecv(args_, sigstop_)) {
         PLOG(ERROR) << "cannot execv('" << args_[0]
                     << "'). See the 'Debugging init' section of init's README.md for tips";
@@ -604,23 +597,13 @@
         return {};
     }
 
-    InterprocessFifo cgroups_activated, setsid_finished;
-
-    if (Result<void> result = cgroups_activated.Initialize(); !result.ok()) {
-        return result;
-    }
+    InterprocessFifo fifo;
+    OR_RETURN(fifo.Initialize());
 
     if (Result<void> result = CheckConsole(); !result.ok()) {
         return result;
     }
 
-    // Only check proc_attr_.console after the CheckConsole() call.
-    if (!proc_attr_.console.empty()) {
-        if (Result<void> result = setsid_finished.Initialize(); !result.ok()) {
-            return result;
-        }
-    }
-
     struct stat sb;
     if (stat(args_[0].c_str(), &sb) == -1) {
         flags_ |= SVC_DISABLED;
@@ -673,13 +656,11 @@
 
     if (pid == 0) {
         umask(077);
-        cgroups_activated.CloseWriteFd();
-        setsid_finished.CloseReadFd();
-        RunService(descriptors, std::move(cgroups_activated), std::move(setsid_finished));
+        fifo.CloseWriteFd();
+        RunService(descriptors, std::move(fifo));
         _exit(127);
     } else {
-        cgroups_activated.CloseReadFd();
-        setsid_finished.CloseWriteFd();
+        fifo.CloseReadFd();
     }
 
     if (pid < 0) {
@@ -708,7 +689,7 @@
                          limit_percent_ != -1 || !limit_property_.empty();
         errno = -createProcessGroup(proc_attr_.uid, pid_, use_memcg);
         if (errno != 0) {
-            Result<void> result = cgroups_activated.Write(0);
+            Result<void> result = fifo.Write(0);
             if (!result.ok()) {
                 return Error() << "Sending notification failed: " << result.error();
             }
@@ -732,27 +713,10 @@
         LmkdRegister(name_, proc_attr_.uid, pid_, oom_score_adjust_);
     }
 
-    if (Result<void> result = cgroups_activated.Write(1); !result.ok()) {
+    if (Result<void> result = fifo.Write(1); !result.ok()) {
         return Error() << "Sending cgroups activated notification failed: " << result.error();
     }
 
-    // Call setpgid() from the parent process to make sure that this call has
-    // finished before the parent process calls kill(-pgid, ...).
-    if (proc_attr_.console.empty()) {
-        if (setpgid(pid, pid) == -1) {
-            return ErrnoError() << "setpgid failed";
-        }
-    } else {
-        // The Read() call below will return an error if the child is killed.
-        if (Result<uint8_t> result = setsid_finished.Read(); !result.ok() || *result != 2) {
-            if (!result.ok()) {
-                return Error() << "Waiting for setsid() failed: " << result.error();
-            } else {
-                return Error() << "Waiting for setsid() failed: " << *result << " <> 2";
-            }
-        }
-    }
-
     NotifyStateChange("running");
     reboot_on_failure.Disable();
     return {};
diff --git a/init/service.h b/init/service.h
index 10a0790..b2c9909 100644
--- a/init/service.h
+++ b/init/service.h
@@ -155,8 +155,7 @@
     void ResetFlagsForStart();
     Result<void> CheckConsole();
     void ConfigureMemcg();
-    void RunService(const std::vector<Descriptor>& descriptors, InterprocessFifo cgroups_activated,
-                    InterprocessFifo setsid_finished);
+    void RunService(const std::vector<Descriptor>& descriptors, InterprocessFifo cgroups_activated);
     void SetMountNamespace();
     static unsigned long next_start_order_;
     static bool is_exec_service_running_;
diff --git a/init/service_utils.cpp b/init/service_utils.cpp
index 56a80b5..a14969e 100644
--- a/init/service_utils.cpp
+++ b/init/service_utils.cpp
@@ -244,11 +244,7 @@
         setsid();
         OpenConsole(attr.console);
     } else {
-        // Without PID namespaces, this call duplicates the setpgid() call from
-        // the parent process. With PID namespaces, this setpgid() call sets the
-        // process group ID for a child of the init process in the PID
-        // namespace.
-        if (setpgid(0, 0) == -1) {
+        if (setpgid(0, getpid()) == -1) {
             return ErrnoError() << "setpgid failed";
         }
         SetupStdio(attr.stdio_to_kmsg);
diff --git a/rootdir/etc/linker.config.json b/rootdir/etc/linker.config.json
index c88c7ff..3a98fdb 100644
--- a/rootdir/etc/linker.config.json
+++ b/rootdir/etc/linker.config.json
@@ -27,6 +27,8 @@
     // statsd
     "libstatspull.so",
     "libstatssocket.so",
+    // tethering LLNDK
+    "libcom.android.tethering.connectivity_native.so",
     // adbd
     "libadb_pairing_auth.so",
     "libadb_pairing_connection.so",
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 123148e..1eec061 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -1223,7 +1223,7 @@
 # controlling access. On older kernels, the paranoid value is the only means of
 # controlling access. It is normally 3 (allow only root), but the shell user
 # can lower it to 1 (allowing thread-scoped pofiling) via security.perf_harden.
-on property:sys.init.perf_lsm_hooks=1
+on load_bpf_programs && property:sys.init.perf_lsm_hooks=1
     write /proc/sys/kernel/perf_event_paranoid -1
 on property:security.perf_harden=0 && property:sys.init.perf_lsm_hooks=""
     write /proc/sys/kernel/perf_event_paranoid 1
diff --git a/trusty/confirmationui/Android.bp b/trusty/confirmationui/Android.bp
index 29ef3c0..c5c5012 100644
--- a/trusty/confirmationui/Android.bp
+++ b/trusty/confirmationui/Android.bp
@@ -53,6 +53,24 @@
     ],
 }
 
+cc_fuzz {
+    name: "android.hardware.confirmationui-service.trusty_fuzzer",
+    defaults: ["service_fuzzer_defaults"],
+    vendor: true,
+    shared_libs: [
+        "android.hardware.confirmationui-V1-ndk",
+        "android.hardware.confirmationui.not-so-secure-input",
+        "android.hardware.confirmationui-lib.trusty",
+        "liblog",
+    ],
+    srcs: ["fuzzer.cpp"],
+    fuzz_config: {
+        cc: [
+            "nyamagoud@google.com",
+        ],
+    },
+}
+
 cc_library {
     name: "android.hardware.confirmationui-lib.trusty",
     defaults: [
diff --git a/trusty/confirmationui/fuzzer.cpp b/trusty/confirmationui/fuzzer.cpp
new file mode 100644
index 0000000..4446b79
--- /dev/null
+++ b/trusty/confirmationui/fuzzer.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 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 <TrustyConfirmationuiHal.h>
+#include <android-base/logging.h>
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using aidl::android::hardware::confirmationui::createTrustyConfirmationUI;
+using aidl::android::hardware::confirmationui::IConfirmationUI;
+using android::fuzzService;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    auto confirmationui = createTrustyConfirmationUI();
+
+    fuzzService(confirmationui->asBinder().get(), FuzzedDataProvider(data, size));
+
+    return 0;
+}
diff --git a/trusty/storage/proxy/rpmb.c b/trusty/storage/proxy/rpmb.c
index f059935..b1b8232 100644
--- a/trusty/storage/proxy/rpmb.c
+++ b/trusty/storage/proxy/rpmb.c
@@ -322,9 +322,9 @@
 }
 
 static int send_mmc_rpmb_req(int mmc_fd, const struct storage_rpmb_send_req* req) {
-    struct {
+    union {
         struct mmc_ioc_multi_cmd multi;
-        struct mmc_ioc_cmd cmd_buf[3];
+        uint8_t raw[sizeof(struct mmc_ioc_multi_cmd) + sizeof(struct mmc_ioc_cmd) * 3];
     } mmc = {};
     struct mmc_ioc_cmd* cmd = mmc.multi.cmds;
     int rc;