Merge "liblp: Remove uses of alignment_offset."
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 8979e9a..ee1ae31 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -1322,6 +1322,8 @@
 
   // Record the total time from device startup to boot complete, regardless of
   // encryption state.
+  // Note: we are recording seconds here even though the field in statsd atom specifies
+  // milliseconds.
   boot_event_store.AddBootEventWithValue(boot_complete_prefix, uptime_s.count());
 
   RecordInitBootTimeProp(&boot_event_store, "ro.boottime.init");
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 12d5d52..9e9557f 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -374,11 +374,11 @@
   ConsumeFd(std::move(output_fd), &result);
 
 #if defined(__aarch64__)
-  ASSERT_MATCH(result, "memory near x0");
+  ASSERT_MATCH(result, "memory near x0 \\(\\[anon:");
 #elif defined(__arm__)
-  ASSERT_MATCH(result, "memory near r0");
+  ASSERT_MATCH(result, "memory near r0 \\(\\[anon:");
 #elif defined(__x86_64__)
-  ASSERT_MATCH(result, "memory near rdi");
+  ASSERT_MATCH(result, "memory near rdi \\(\\[anon:");
 #else
   ASSERT_TRUE(false) << "unsupported architecture";
 #endif
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index c1a59d8..4f75ff1 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -42,6 +42,7 @@
 #include <android-base/unique_fd.h>
 #include <android/log.h>
 #include <async_safe/log.h>
+#include <bionic/macros.h>
 #include <log/log.h>
 #include <log/log_read.h>
 #include <log/logprint.h>
@@ -362,7 +363,7 @@
   regs->IterateRegisters([log, maps, memory](const char* reg_name, uint64_t reg_value) {
     std::string label{"memory near "s + reg_name};
     if (maps) {
-      unwindstack::MapInfo* map_info = maps->Find(reg_value);
+      unwindstack::MapInfo* map_info = maps->Find(untag_address(reg_value));
       if (map_info != nullptr && !map_info->name.empty()) {
         label += " (" + map_info->name + ")";
       }
@@ -592,7 +593,6 @@
   }
 
   ProcessInfo process_info;
-  unique_fd attr_fd(open("/proc/self/attr/current", O_RDONLY | O_CLOEXEC));
   process_info.abort_msg_address = abort_msg_address;
   engrave_tombstone(unique_fd(dup(tombstone_fd)), unique_fd(dup(proto_fd)), &unwinder, threads, tid,
                     process_info, nullptr, nullptr);
diff --git a/debuggerd/libdebuggerd/tombstone_proto.cpp b/debuggerd/libdebuggerd/tombstone_proto.cpp
index bb3c7ea..23ca070 100644
--- a/debuggerd/libdebuggerd/tombstone_proto.cpp
+++ b/debuggerd/libdebuggerd/tombstone_proto.cpp
@@ -39,6 +39,7 @@
 #include <android-base/unique_fd.h>
 
 #include <android/log.h>
+#include <bionic/macros.h>
 #include <log/log.h>
 #include <log/log_read.h>
 #include <log/logprint.h>
@@ -233,7 +234,7 @@
 
           dump.set_register_name(name);
 
-          unwindstack::MapInfo* map_info = maps->Find(value);
+          unwindstack::MapInfo* map_info = maps->Find(untag_address(value));
           if (map_info) {
             dump.set_mapping_name(map_info->name);
           }
diff --git a/fastboot/device/usb_client.cpp b/fastboot/device/usb_client.cpp
index 2caced4..3f9b0f0 100644
--- a/fastboot/device/usb_client.cpp
+++ b/fastboot/device/usb_client.cpp
@@ -283,7 +283,7 @@
     size_t bytes_written_total = 0;
     while (bytes_written_total < len) {
         auto bytes_to_write = std::min(len - bytes_written_total, kFbFfsNumBufs * kFbFfsBufSize);
-        auto bytes_written_now = handle_->write(handle_.get(), data, bytes_to_write);
+        auto bytes_written_now = handle_->write(handle_.get(), char_data, bytes_to_write);
         if (bytes_written_now < 0) {
             return bytes_written_total == 0 ? -1 : bytes_written_total;
         }
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index f7edf8e..38be934 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -1103,6 +1103,7 @@
 static std::string get_current_slot() {
     std::string current_slot;
     if (fb->GetVar("current-slot", &current_slot) != fastboot::SUCCESS) return "";
+    if (current_slot[0] == '_') current_slot.erase(0, 1);
     return current_slot;
 }
 
@@ -1950,6 +1951,7 @@
             if (slot_override == "") {
                 std::string current_slot;
                 if (fb->GetVar("current-slot", &current_slot) == fastboot::SUCCESS) {
+                    if (current_slot[0] == '_') current_slot.erase(0, 1);
                     next_active = verify_slot(current_slot, false);
                 } else {
                     wants_set_active = false;
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 1efe793..6952cdf 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -2203,7 +2203,8 @@
     // Devices upgrading to dynamic partitions are allowed to specify a super
     // partition name. This includes cuttlefish, which is a non-A/B device.
     std::string super_partition;
-    if (fs_mgr_get_boot_config_from_kernel_cmdline("super_partition", &super_partition)) {
+    if (fs_mgr_get_boot_config_from_bootconfig_source("super_partition", &super_partition) ||
+        fs_mgr_get_boot_config_from_kernel_cmdline("super_partition", &super_partition)) {
         if (fs_mgr_get_slot_suffix().empty()) {
             return super_partition;
         }
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 8ac3361..0c0862e 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -299,7 +299,8 @@
 std::string InitAndroidDtDir() {
     std::string android_dt_dir;
     // The platform may specify a custom Android DT path in kernel cmdline
-    if (!fs_mgr_get_boot_config_from_kernel_cmdline("android_dt_dir", &android_dt_dir)) {
+    if (!fs_mgr_get_boot_config_from_bootconfig_source("android_dt_dir", &android_dt_dir) &&
+        !fs_mgr_get_boot_config_from_kernel_cmdline("android_dt_dir", &android_dt_dir)) {
         // Fall back to the standard procfs-based path
         android_dt_dir = kDefaultAndroidDtDir;
     }
@@ -412,7 +413,8 @@
 
         if (!fs_mgr_get_boot_config(prop, &suffix)) continue;
 
-        for (const char* prefix : {"/odm/etc/fstab.", "/vendor/etc/fstab.", "/fstab."}) {
+        for (const char* prefix :
+             {"/odm/etc/fstab.", "/vendor/etc/fstab.", "/fstab.", "/first_stage_ramdisk/fstab."}) {
             std::string fstab_path = prefix + suffix;
             if (access(fstab_path.c_str(), F_OK) == 0) {
                 return fstab_path;
@@ -841,9 +843,22 @@
 }
 
 std::set<std::string> GetBootDevices() {
-    // First check the kernel commandline, then try the device tree otherwise
+    // First check bootconfig, then kernel commandline, then the device tree
     std::string dt_file_name = get_android_dt_dir() + "/boot_devices";
     std::string value;
+    if (fs_mgr_get_boot_config_from_bootconfig_source("boot_devices", &value) ||
+        fs_mgr_get_boot_config_from_bootconfig_source("boot_device", &value)) {
+        std::set<std::string> boot_devices;
+        // remove quotes and split by spaces
+        auto boot_device_strings = base::Split(base::StringReplace(value, "\"", "", true), " ");
+        for (std::string_view device : boot_device_strings) {
+            // trim the trailing comma, keep the rest.
+            base::ConsumeSuffix(&device, ",");
+            boot_devices.emplace(device);
+        }
+        return boot_devices;
+    }
+
     if (fs_mgr_get_boot_config_from_kernel_cmdline("boot_devices", &value) ||
         ReadDtFile(dt_file_name, &value)) {
         auto boot_devices = Split(value, ",");
diff --git a/fs_mgr/libfiemap/image_manager.cpp b/fs_mgr/libfiemap/image_manager.cpp
index 841f215..44f659b 100644
--- a/fs_mgr/libfiemap/image_manager.cpp
+++ b/fs_mgr/libfiemap/image_manager.cpp
@@ -16,6 +16,8 @@
 
 #include <libfiemap/image_manager.h>
 
+#include <optional>
+
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/properties.h>
@@ -574,7 +576,7 @@
         return false;
     }
     auto& dm = DeviceMapper::Instance();
-    LoopControl loop;
+    std::optional<LoopControl> loop;
 
     std::string status;
     auto status_file = GetStatusFilePath(name);
@@ -598,9 +600,14 @@
                 return false;
             }
         } else if (pieces[0] == "loop") {
+            // Lazily connect to loop-control to avoid spurious errors in recovery.
+            if (!loop.has_value()) {
+                loop.emplace();
+            }
+
             // Failure to remove a loop device is not fatal, since we can still
             // remove the backing file if we want.
-            loop.Detach(pieces[1]);
+            loop->Detach(pieces[1]);
         } else {
             LOG(ERROR) << "Unknown status: " << pieces[0];
         }
diff --git a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
index 42bff14..b4e92a2 100644
--- a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
+++ b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
@@ -46,7 +46,7 @@
     SECOND_PHASE = 2;
 }
 
-// Next: 11
+// Next: 12
 message SnapshotStatus {
     // Name of the snapshot. This is usually the name of the snapshotted
     // logical partition; for example, "system_b".
@@ -102,6 +102,9 @@
 
     // The old partition size (if none existed, this will be zero).
     uint64 old_partition_size = 10;
+
+    // Compression algorithm (none, gz, or brotli).
+    string compression_algorithm = 11;
 }
 
 // Next: 8
diff --git a/fs_mgr/libsnapshot/dm_snapshot_internals.h b/fs_mgr/libsnapshot/dm_snapshot_internals.h
index fef256d..ed77c15 100644
--- a/fs_mgr/libsnapshot/dm_snapshot_internals.h
+++ b/fs_mgr/libsnapshot/dm_snapshot_internals.h
@@ -14,8 +14,10 @@
 
 #pragma once
 
+#include <android-base/logging.h>
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
 namespace android {
@@ -26,19 +28,46 @@
     DmSnapCowSizeCalculator(unsigned int sector_bytes, unsigned int chunk_sectors)
         : sector_bytes_(sector_bytes),
           chunk_sectors_(chunk_sectors),
-          exceptions_per_chunk(chunk_sectors_ * sector_bytes_ / (64 * 2 / 8)) {}
+          exceptions_per_chunk(chunk_sectors_ * sector_bytes_ / exception_size_bytes) {}
 
     void WriteByte(uint64_t address) { WriteSector(address / sector_bytes_); }
     void WriteSector(uint64_t sector) { WriteChunk(sector / chunk_sectors_); }
     void WriteChunk(uint64_t chunk_id) {
-        if (modified_chunks_.size() <= chunk_id) {
-            modified_chunks_.resize(chunk_id + 1, false);
+        if (!valid_) {
+            return;
         }
+
+        if (modified_chunks_.size() <= chunk_id) {
+            if (modified_chunks_.max_size() <= chunk_id) {
+                LOG(ERROR) << "Invalid COW size, chunk_id is too large.";
+                valid_ = false;
+                return;
+            }
+            modified_chunks_.resize(chunk_id + 1, false);
+            if (modified_chunks_.size() <= chunk_id) {
+                LOG(ERROR) << "Invalid COW size, chunk_id is too large.";
+                valid_ = false;
+                return;
+            }
+        }
+
         modified_chunks_[chunk_id] = true;
     }
 
-    uint64_t cow_size_bytes() const { return cow_size_sectors() * sector_bytes_; }
-    uint64_t cow_size_sectors() const { return cow_size_chunks() * chunk_sectors_; }
+    std::optional<uint64_t> cow_size_bytes() const {
+        auto sectors = cow_size_sectors();
+        if (!sectors) {
+            return std::nullopt;
+        }
+        return sectors.value() * sector_bytes_;
+    }
+    std::optional<uint64_t> cow_size_sectors() const {
+        auto chunks = cow_size_chunks();
+        if (!chunks) {
+            return std::nullopt;
+        }
+        return chunks.value() * chunk_sectors_;
+    }
 
     /*
      * The COW device has a precise internal structure as follows:
@@ -56,7 +85,12 @@
      *   - chunks addressable by previous map (exceptions_per_chunk)
      * - 1 extra chunk
      */
-    uint64_t cow_size_chunks() const {
+    std::optional<uint64_t> cow_size_chunks() const {
+        if (!valid_) {
+            LOG(ERROR) << "Invalid COW size.";
+            return std::nullopt;
+        }
+
         uint64_t modified_chunks_count = 0;
         uint64_t cow_chunks = 0;
 
@@ -90,19 +124,30 @@
     const uint64_t chunk_sectors_;
 
     /*
-     * The COW device stores tables to map the modified chunks. Each table
-     * has the size of exactly 1 chunk.
-     * Each row of the table (also called exception in the kernel) contains two
-     * 64 bit indices to identify the corresponding chunk, and this 128 bit row
-     * size is a constant.
-     * The number of exceptions that each table can contain determines the
-     * number of data chunks that separate two consecutive tables. This value
-     * is then fundamental to compute the space overhead introduced by the
-     * tables in COW devices.
+     * The COW device stores tables to map the modified chunks. Each table has
+     * the size of exactly 1 chunk.
+     * Each entry of the table is called exception and the number of exceptions
+     * that each table can contain determines the number of data chunks that
+     * separate two consecutive tables. This value is then fundamental to
+     * compute the space overhead introduced by the tables in COW devices.
      */
     const uint64_t exceptions_per_chunk;
 
     /*
+     * Each row of the table (called exception in the kernel) contains two
+     * 64 bit indices to identify the corresponding chunk, and this 128 bit
+     * pair is constant in size.
+     */
+    static constexpr unsigned int exception_size_bytes = 64 * 2 / 8;
+
+    /*
+     * Validity check for the container.
+     * It may happen that the caller attempts the write of an invalid chunk
+     * identifier, and this misbehavior is accounted and stored in this value.
+     */
+    bool valid_ = true;
+
+    /*
      * |modified_chunks_| is a container that keeps trace of the modified
      * chunks.
      * Multiple options were considered when choosing the most appropriate data
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
index 0d90f6c..a79a86d 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
@@ -694,8 +694,8 @@
     // Call ProcessUpdateState and handle states with special rules before data wipe. Specifically,
     // if |allow_forward_merge| and allow-forward-merge indicator exists, initiate merge if
     // necessary.
-    bool ProcessUpdateStateOnDataWipe(bool allow_forward_merge,
-                                      const std::function<bool()>& callback);
+    UpdateState ProcessUpdateStateOnDataWipe(bool allow_forward_merge,
+                                             const std::function<bool()>& callback);
 
     // Return device string of a mapped image, or if it is not available, the mapped image path.
     bool GetMappedImageDeviceStringOrPath(const std::string& device_name,
diff --git a/fs_mgr/libsnapshot/partition_cow_creator.cpp b/fs_mgr/libsnapshot/partition_cow_creator.cpp
index da6fc9d..6002043 100644
--- a/fs_mgr/libsnapshot/partition_cow_creator.cpp
+++ b/fs_mgr/libsnapshot/partition_cow_creator.cpp
@@ -142,11 +142,11 @@
     }
 }
 
-uint64_t PartitionCowCreator::GetCowSize() {
+std::optional<uint64_t> PartitionCowCreator::GetCowSize() {
     if (compression_enabled) {
         if (update == nullptr || !update->has_estimate_cow_size()) {
             LOG(ERROR) << "Update manifest does not include a COW size";
-            return 0;
+            return std::nullopt;
         }
 
         // Add an extra 2MB of wiggle room for any minor differences in labels/metadata
@@ -239,7 +239,7 @@
     }
 
     // Compute the COW partition size.
-    uint64_t cow_partition_size = std::min(cow_size, free_region_length);
+    uint64_t cow_partition_size = std::min(cow_size.value(), free_region_length);
     // Round it down to the nearest logical block. Logical partitions must be a multiple
     // of logical blocks.
     cow_partition_size &= ~(logical_block_size - 1);
@@ -247,7 +247,7 @@
     // Assign cow_partition_usable_regions to indicate what regions should the COW partition uses.
     ret.cow_partition_usable_regions = std::move(free_regions);
 
-    auto cow_file_size = cow_size - cow_partition_size;
+    auto cow_file_size = cow_size.value() - cow_partition_size;
     // Round it up to the nearest sector.
     cow_file_size += kSectorSize - 1;
     cow_file_size &= ~(kSectorSize - 1);
diff --git a/fs_mgr/libsnapshot/partition_cow_creator.h b/fs_mgr/libsnapshot/partition_cow_creator.h
index 64d186b..34b39ca 100644
--- a/fs_mgr/libsnapshot/partition_cow_creator.h
+++ b/fs_mgr/libsnapshot/partition_cow_creator.h
@@ -58,6 +58,7 @@
     std::vector<ChromeOSExtent> extra_extents = {};
     // True if compression is enabled.
     bool compression_enabled = false;
+    std::string compression_algorithm;
 
     struct Return {
         SnapshotStatus snapshot_status;
@@ -68,7 +69,7 @@
 
   private:
     bool HasExtent(Partition* p, Extent* e);
-    uint64_t GetCowSize();
+    std::optional<uint64_t> GetCowSize();
 };
 
 }  // namespace snapshot
diff --git a/fs_mgr/libsnapshot/partition_cow_creator_test.cpp b/fs_mgr/libsnapshot/partition_cow_creator_test.cpp
index e4b476f..de35c13 100644
--- a/fs_mgr/libsnapshot/partition_cow_creator_test.cpp
+++ b/fs_mgr/libsnapshot/partition_cow_creator_test.cpp
@@ -308,6 +308,10 @@
         cc.WriteByte(b);
         ASSERT_EQ(cc.cow_size_sectors(), 40);
     }
+
+    // Write a byte that would surely overflow the counter
+    cc.WriteChunk(std::numeric_limits<uint64_t>::max());
+    ASSERT_FALSE(cc.cow_size_sectors().has_value());
 }
 
 void BlocksToExtents(const std::vector<uint64_t>& blocks,
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index eb3a501..ca4c265 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -359,6 +359,7 @@
     status->set_sectors_allocated(0);
     status->set_metadata_sectors(0);
     status->set_compression_enabled(cow_creator->compression_enabled);
+    status->set_compression_algorithm(cow_creator->compression_algorithm);
 
     if (!WriteSnapshotStatus(lock, *status)) {
         PLOG(ERROR) << "Could not write snapshot status: " << status->name();
@@ -894,6 +895,8 @@
                                                 const std::function<bool()>& before_cancel) {
     while (true) {
         UpdateState state = CheckMergeState(before_cancel);
+        LOG(INFO) << "ProcessUpdateState handling state: " << state;
+
         if (state == UpdateState::MergeFailed) {
             AcknowledgeMergeFailure();
         }
@@ -920,13 +923,15 @@
     }
 
     UpdateState state = CheckMergeState(lock.get(), before_cancel);
+    LOG(INFO) << "CheckMergeState for snapshots returned: " << state;
+
     if (state == UpdateState::MergeCompleted) {
         // Do this inside the same lock. Failures get acknowledged without the
         // lock, because flock() might have failed.
         AcknowledgeMergeSuccess(lock.get());
     } else if (state == UpdateState::Cancelled) {
-        if (!RemoveAllUpdateState(lock.get(), before_cancel)) {
-            return ReadSnapshotUpdateStatus(lock.get()).state();
+        if (!device_->IsRecovery() && !RemoveAllUpdateState(lock.get(), before_cancel)) {
+            LOG(ERROR) << "Failed to remove all update state after acknowleding cancelled update.";
         }
     }
     return state;
@@ -968,13 +973,23 @@
         return UpdateState::MergeFailed;
     }
 
+    auto other_suffix = device_->GetOtherSlotSuffix();
+
     bool cancelled = false;
     bool failed = false;
     bool merging = false;
     bool needs_reboot = false;
     bool wrong_phase = false;
     for (const auto& snapshot : snapshots) {
+        if (android::base::EndsWith(snapshot, other_suffix)) {
+            // This will have triggered an error message in InitiateMerge already.
+            LOG(INFO) << "Skipping merge validation of unexpected snapshot: " << snapshot;
+            continue;
+        }
+
         UpdateState snapshot_state = CheckTargetMergeState(lock, snapshot, update_status);
+        LOG(INFO) << "CheckTargetMergeState for " << snapshot << " returned: " << snapshot_state;
+
         switch (snapshot_state) {
             case UpdateState::MergeFailed:
                 failed = true;
@@ -1173,7 +1188,7 @@
     // indicator that cleanup is needed on reboot. If a factory data reset
     // was requested, it doesn't matter, everything will get wiped anyway.
     // To make testing easier we consider a /data wipe as cleaned up.
-    if (device_->IsRecovery() && !in_factory_data_reset_) {
+    if (device_->IsRecovery()) {
         WriteUpdateState(lock, UpdateState::MergeCompleted);
         return;
     }
@@ -1692,6 +1707,7 @@
     for (const auto& snapshot : snapshots) {
         DmTargetSnapshot::Status current_status;
 
+        if (!IsSnapshotDevice(snapshot)) continue;
         if (!QuerySnapshotStatus(snapshot, nullptr, &current_status)) continue;
 
         fake_snapshots_status.sectors_allocated += current_status.sectors_allocated;
@@ -2645,9 +2661,20 @@
     // these devices.
     AutoDeviceList created_devices;
 
-    bool use_compression = IsCompressionEnabled() &&
-                           manifest.dynamic_partition_metadata().vabc_enabled() &&
-                           !device_->IsRecovery();
+    const auto& dap_metadata = manifest.dynamic_partition_metadata();
+    bool use_compression =
+            IsCompressionEnabled() && dap_metadata.vabc_enabled() && !device_->IsRecovery();
+
+    std::string compression_algorithm;
+    if (use_compression) {
+        compression_algorithm = dap_metadata.vabc_compression_param();
+        if (compression_algorithm.empty()) {
+            // Older OTAs don't set an explicit compression type, so default to gz.
+            compression_algorithm = "gz";
+        }
+    } else {
+        compression_algorithm = "none";
+    }
 
     PartitionCowCreator cow_creator{
             .target_metadata = target_metadata.get(),
@@ -2658,6 +2685,7 @@
             .update = nullptr,
             .extra_extents = {},
             .compression_enabled = use_compression,
+            .compression_algorithm = compression_algorithm,
     };
 
     auto ret = CreateUpdateSnapshotsInternal(lock.get(), manifest, &cow_creator, &created_devices,
@@ -2902,7 +2930,7 @@
                 return Return::Error();
             }
 
-            CowWriter writer(CowOptions{});
+            CowWriter writer(CowOptions{.compression = it->second.compression_algorithm()});
             if (!writer.Initialize(fd) || !writer.Finalize()) {
                 LOG(ERROR) << "Could not initialize COW device for " << target_partition->name();
                 return Return::Error();
@@ -3009,7 +3037,7 @@
     CHECK(lock);
 
     CowOptions cow_options;
-    cow_options.compression = "gz";
+    cow_options.compression = status.compression_algorithm();
     cow_options.max_blocks = {status.device_size() / cow_options.block_size};
 
     // Currently we don't support partial snapshots, since partition_cow_creator
@@ -3148,6 +3176,7 @@
         ss << "    cow file size (bytes): " << status.cow_file_size() << std::endl;
         ss << "    allocated sectors: " << status.sectors_allocated() << std::endl;
         ss << "    metadata sectors: " << status.metadata_sectors() << std::endl;
+        ss << "    compression: " << status.compression_algorithm() << std::endl;
     }
     os << ss.rdbuf();
     return ok;
@@ -3212,10 +3241,11 @@
     };
 
     in_factory_data_reset_ = true;
-    bool ok = ProcessUpdateStateOnDataWipe(true /* allow_forward_merge */, process_callback);
+    UpdateState state =
+            ProcessUpdateStateOnDataWipe(true /* allow_forward_merge */, process_callback);
     in_factory_data_reset_ = false;
 
-    if (!ok) {
+    if (state == UpdateState::MergeFailed) {
         return false;
     }
 
@@ -3223,6 +3253,16 @@
     if (!UnmapAllPartitionsInRecovery()) {
         LOG(ERROR) << "Unable to unmap all partitions; fastboot may fail to flash.";
     }
+
+    if (state != UpdateState::None) {
+        auto lock = LockExclusive();
+        if (!lock) return false;
+
+        // Zap the update state so the bootloader doesn't think we're still
+        // merging. It's okay if this fails, it's informative only at this
+        // point.
+        WriteUpdateState(lock.get(), UpdateState::None);
+    }
     return true;
 }
 
@@ -3257,15 +3297,15 @@
     return true;
 }
 
-bool SnapshotManager::ProcessUpdateStateOnDataWipe(bool allow_forward_merge,
-                                                   const std::function<bool()>& callback) {
+UpdateState SnapshotManager::ProcessUpdateStateOnDataWipe(bool allow_forward_merge,
+                                                          const std::function<bool()>& callback) {
     auto slot_number = SlotNumberForSlotSuffix(device_->GetSlotSuffix());
     UpdateState state = ProcessUpdateState(callback);
     LOG(INFO) << "Update state in recovery: " << state;
     switch (state) {
         case UpdateState::MergeFailed:
             LOG(ERROR) << "Unrecoverable merge failure detected.";
-            return false;
+            return state;
         case UpdateState::Unverified: {
             // If an OTA was just applied but has not yet started merging:
             //
@@ -3285,8 +3325,12 @@
                 if (allow_forward_merge &&
                     access(GetForwardMergeIndicatorPath().c_str(), F_OK) == 0) {
                     LOG(INFO) << "Forward merge allowed, initiating merge now.";
-                    return InitiateMerge() &&
-                           ProcessUpdateStateOnDataWipe(false /* allow_forward_merge */, callback);
+
+                    if (!InitiateMerge()) {
+                        LOG(ERROR) << "Failed to initiate merge on data wipe.";
+                        return UpdateState::MergeFailed;
+                    }
+                    return ProcessUpdateStateOnDataWipe(false /* allow_forward_merge */, callback);
                 }
 
                 LOG(ERROR) << "Reverting to old slot since update will be deleted.";
@@ -3304,7 +3348,7 @@
         default:
             break;
     }
-    return true;
+    return state;
 }
 
 bool SnapshotManager::EnsureNoOverflowSnapshot(LockedFile* lock) {
diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp
index d57aa6c..25500b5 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -423,6 +423,11 @@
 
     PartitionCowCreator cow_creator;
     cow_creator.compression_enabled = IsCompressionEnabled();
+    if (cow_creator.compression_enabled) {
+        cow_creator.compression_algorithm = "gz";
+    } else {
+        cow_creator.compression_algorithm = "none";
+    }
 
     static const uint64_t kDeviceSize = 1024 * 1024;
     SnapshotStatus status;
@@ -446,6 +451,7 @@
         ASSERT_EQ(status.device_size(), kDeviceSize);
         ASSERT_EQ(status.snapshot_size(), kDeviceSize);
         ASSERT_EQ(status.compression_enabled(), cow_creator.compression_enabled);
+        ASSERT_EQ(status.compression_algorithm(), cow_creator.compression_algorithm);
     }
 
     ASSERT_TRUE(sm->UnmapSnapshot(lock_.get(), "test-snapshot"));
@@ -576,6 +582,11 @@
     SnapshotStatus status;
     ASSERT_TRUE(init->ReadSnapshotStatus(lock_.get(), "test_partition_b", &status));
     ASSERT_EQ(status.state(), SnapshotState::CREATED);
+    if (IsCompressionEnabled()) {
+        ASSERT_EQ(status.compression_algorithm(), "gz");
+    } else {
+        ASSERT_EQ(status.compression_algorithm(), "none");
+    }
 
     DeviceMapper::TargetInfo target;
     ASSERT_TRUE(init->IsSnapshotDevice("test_partition_b", &target));
@@ -636,8 +647,8 @@
 
     // Because the status is Merging, we must call ProcessUpdateState, which should
     // detect a cancelled update.
-    ASSERT_EQ(sm->ProcessUpdateState(), UpdateState::Cancelled);
-    ASSERT_EQ(sm->GetUpdateState(), UpdateState::None);
+    ASSERT_EQ(init->ProcessUpdateState(), UpdateState::Cancelled);
+    ASSERT_EQ(init->GetUpdateState(), UpdateState::None);
 }
 
 TEST_F(SnapshotTest, UpdateBootControlHal) {
@@ -1767,7 +1778,7 @@
     ASSERT_TRUE(new_sm->HandleImminentDataWipe());
     // Manually mount metadata so that we can call GetUpdateState() below.
     MountMetadata();
-    EXPECT_EQ(new_sm->GetUpdateState(), UpdateState::Unverified);
+    EXPECT_EQ(new_sm->GetUpdateState(), UpdateState::None);
     EXPECT_TRUE(test_device->IsSlotUnbootable(1));
     EXPECT_FALSE(test_device->IsSlotUnbootable(0));
 }
@@ -2105,8 +2116,12 @@
 
     // There should be no snapshot to merge.
     auto new_sm = SnapshotManager::New(new TestDeviceInfo(fake_super, flashed_slot_suffix));
-    // update_enigne calls ProcessUpdateState first -- should see Cancelled.
-    ASSERT_EQ(UpdateState::Cancelled, new_sm->ProcessUpdateState());
+    if (flashed_slot == 0 && after_merge) {
+        ASSERT_EQ(UpdateState::MergeCompleted, new_sm->ProcessUpdateState());
+    } else {
+        // update_engine calls ProcessUpdateState first -- should see Cancelled.
+        ASSERT_EQ(UpdateState::Cancelled, new_sm->ProcessUpdateState());
+    }
 
     // Next OTA calls CancelUpdate no matter what.
     ASSERT_TRUE(new_sm->CancelUpdate());
diff --git a/fs_mgr/libsnapshot/snapuserd.cpp b/fs_mgr/libsnapshot/snapuserd.cpp
index d620300..4c4a342 100644
--- a/fs_mgr/libsnapshot/snapuserd.cpp
+++ b/fs_mgr/libsnapshot/snapuserd.cpp
@@ -447,16 +447,15 @@
 }
 
 void Snapuserd::CheckMergeCompletionStatus() {
-    CowHeader header;
-
-    if (merge_initiated_) {
-        reader_->GetHeader(&header);
-        SNAP_LOG(INFO) << "Merge-status: Total-Merged-ops: " << header.num_merge_ops
-                       << " Total-data-ops: " << reader_->total_data_ops();
-    } else {
-        SNAP_LOG(INFO) << "Merge was not initiated. Total-Merged-ops: " << header.num_merge_ops
-                       << " Total-data-ops: " << reader_->total_data_ops();
+    if (!merge_initiated_) {
+        SNAP_LOG(INFO) << "Merge was not initiated. Total-data-ops: " << reader_->total_data_ops();
+        return;
     }
+
+    CowHeader header;
+    reader_->GetHeader(&header);
+    SNAP_LOG(INFO) << "Merge-status: Total-Merged-ops: " << header.num_merge_ops
+                   << " Total-data-ops: " << reader_->total_data_ops();
 }
 
 /*
diff --git a/fs_mgr/libsnapshot/update_engine/update_metadata.proto b/fs_mgr/libsnapshot/update_engine/update_metadata.proto
index 4a97f81..f31ee31 100644
--- a/fs_mgr/libsnapshot/update_engine/update_metadata.proto
+++ b/fs_mgr/libsnapshot/update_engine/update_metadata.proto
@@ -74,6 +74,7 @@
 message DynamicPartitionMetadata {
     repeated DynamicPartitionGroup groups = 1;
     optional bool vabc_enabled = 3;
+    optional string vabc_compression_param = 4;
 }
 
 message DeltaArchiveManifest {
diff --git a/fs_mgr/tests/fs_mgr_test.cpp b/fs_mgr/tests/fs_mgr_test.cpp
index 62a8d3b..bcd5180 100644
--- a/fs_mgr/tests/fs_mgr_test.cpp
+++ b/fs_mgr/tests/fs_mgr_test.cpp
@@ -121,6 +121,7 @@
 
 const std::string bootconfig =
         "androidboot.bootdevice  = \" \"1d84000.ufshc\"\n"
+        "androidboot.boot_devices = \"dev1\", \"dev2,withcomma\", \"dev3\"\n"
         "androidboot.baseband = \"sdy\"\n"
         "androidboot.keymaster = \"1\"\n"
         "androidboot.serialno = \"BLAHBLAHBLAH\"\n"
@@ -152,6 +153,7 @@
 
 const std::vector<std::pair<std::string, std::string>> bootconfig_result_space = {
         {"androidboot.bootdevice", "1d84000.ufshc"},
+        {"androidboot.boot_devices", "dev1, dev2,withcomma, dev3"},
         {"androidboot.baseband", "sdy"},
         {"androidboot.keymaster", "1"},
         {"androidboot.serialno", "BLAHBLAHBLAH"},
diff --git a/init/Android.bp b/init/Android.bp
index 3ff1767..1381c1d 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -143,6 +143,7 @@
         "libcgrouprc_format",
         "liblmkd_utils",
         "libmodprobe",
+        "libprocinfo",
         "libprotobuf-cpp-lite",
         "libpropertyinfoserializer",
         "libpropertyinfoparser",
@@ -308,6 +309,7 @@
         "libsnapshot_cow",
         "libsnapshot_init",
         "update_metadata-protos",
+        "libprocinfo",
     ],
 
     static_executable: true,
diff --git a/init/Android.mk b/init/Android.mk
index 65ee385..3c7d95a 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -130,6 +130,7 @@
     libsnapshot_cow \
     libsnapshot_init \
     update_metadata-protos \
+    libprocinfo \
 
 LOCAL_SANITIZE := signed-integer-overflow
 # First stage init is weird: it may start without stdout/stderr, and no /proc.
diff --git a/init/builtins.cpp b/init/builtins.cpp
index dcc9582..035038f 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -1278,6 +1278,14 @@
         return ErrnoError() << "failed to execute linkerconfig";
     }
 
+    auto current_mount_ns = GetCurrentMountNamespace();
+    if (!current_mount_ns.ok()) {
+        return current_mount_ns.error();
+    }
+    if (*current_mount_ns == NS_DEFAULT) {
+        SetDefaultMountNamespaceReady();
+    }
+
     LOG(INFO) << "linkerconfig generated " << linkerconfig_target
               << " with mounted APEX modules info";
 
diff --git a/init/first_stage_console.cpp b/init/first_stage_console.cpp
index 0f01166..e2ea0ab 100644
--- a/init/first_stage_console.cpp
+++ b/init/first_stage_console.cpp
@@ -105,8 +105,20 @@
     _exit(127);
 }
 
-int FirstStageConsole(const std::string& cmdline) {
-    auto pos = cmdline.find("androidboot.first_stage_console=");
+int FirstStageConsole(const std::string& cmdline, const std::string& bootconfig) {
+    auto pos = bootconfig.find("androidboot.first_stage_console =");
+    if (pos != std::string::npos) {
+        int val = 0;
+        if (sscanf(bootconfig.c_str() + pos, "androidboot.first_stage_console = \"%d\"", &val) !=
+            1) {
+            return FirstStageConsoleParam::DISABLED;
+        }
+        if (val <= FirstStageConsoleParam::MAX_PARAM_VALUE && val >= 0) {
+            return val;
+        }
+    }
+
+    pos = cmdline.find("androidboot.first_stage_console=");
     if (pos != std::string::npos) {
         int val = 0;
         if (sscanf(cmdline.c_str() + pos, "androidboot.first_stage_console=%d", &val) != 1) {
diff --git a/init/first_stage_console.h b/init/first_stage_console.h
index d5744df..4a30d35 100644
--- a/init/first_stage_console.h
+++ b/init/first_stage_console.h
@@ -29,7 +29,7 @@
 };
 
 void StartConsole(const std::string& cmdline);
-int FirstStageConsole(const std::string& cmdline);
+int FirstStageConsole(const std::string& cmdline, const std::string& bootconfig);
 
 }  // namespace init
 }  // namespace android
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index ff75aa3..b2ab550 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -102,8 +102,9 @@
     }
 }
 
-bool ForceNormalBoot(const std::string& cmdline) {
-    return cmdline.find("androidboot.force_normal_boot=1") != std::string::npos;
+bool ForceNormalBoot(const std::string& cmdline, const std::string& bootconfig) {
+    return bootconfig.find("androidboot.force_normal_boot = \"1\"") != std::string::npos ||
+           cmdline.find("androidboot.force_normal_boot=1") != std::string::npos;
 }
 
 }  // namespace
@@ -211,6 +212,8 @@
     android::base::ReadFileToString("/proc/cmdline", &cmdline);
     // Don't expose the raw bootconfig to unprivileged processes.
     chmod("/proc/bootconfig", 0440);
+    std::string bootconfig;
+    android::base::ReadFileToString("/proc/bootconfig", &bootconfig);
     gid_t groups[] = {AID_READPROC};
     CHECKCALL(setgroups(arraysize(groups), groups));
     CHECKCALL(mount("sysfs", "/sys", "sysfs", 0, NULL));
@@ -278,11 +281,11 @@
         old_root_dir.reset();
     }
 
-    auto want_console = ALLOW_FIRST_STAGE_CONSOLE ? FirstStageConsole(cmdline) : 0;
+    auto want_console = ALLOW_FIRST_STAGE_CONSOLE ? FirstStageConsole(cmdline, bootconfig) : 0;
 
     boot_clock::time_point module_start_time = boot_clock::now();
     int module_count = 0;
-    if (!LoadKernelModules(IsRecoveryMode() && !ForceNormalBoot(cmdline), want_console,
+    if (!LoadKernelModules(IsRecoveryMode() && !ForceNormalBoot(cmdline, bootconfig), want_console,
                            module_count)) {
         if (want_console != FirstStageConsoleParam::DISABLED) {
             LOG(ERROR) << "Failed to load kernel modules, starting console";
@@ -324,7 +327,7 @@
         LOG(INFO) << "Copied ramdisk prop to " << dest;
     }
 
-    if (ForceNormalBoot(cmdline)) {
+    if (ForceNormalBoot(cmdline, bootconfig)) {
         mkdir("/first_stage_ramdisk", 0755);
         // SwitchRoot() must be called with a mount point as the target, so we bind mount the
         // target directory to itself here.
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index de72f23..a11bb28 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -44,6 +44,7 @@
 
 #include "block_dev_initializer.h"
 #include "devices.h"
+#include "result.h"
 #include "snapuserd_transition.h"
 #include "switch_root.h"
 #include "uevent.h"
@@ -51,6 +52,7 @@
 #include "util.h"
 
 using android::base::ReadFileToString;
+using android::base::Result;
 using android::base::Split;
 using android::base::StringPrintf;
 using android::base::Timer;
@@ -81,7 +83,7 @@
 
     // The factory method to create either FirstStageMountVBootV1 or FirstStageMountVBootV2
     // based on device tree configurations.
-    static std::unique_ptr<FirstStageMount> Create();
+    static Result<std::unique_ptr<FirstStageMount>> Create();
     bool DoCreateDevices();    // Creates devices and logical partitions from storage devices
     bool DoFirstStageMount();  // Mounts fstab entries read from device tree.
     bool InitDevices();
@@ -160,7 +162,7 @@
     return is_android_dt_value_expected("vbmeta/compatible", "android,vbmeta");
 }
 
-static Fstab ReadFirstStageFstab() {
+static Result<Fstab> ReadFirstStageFstab() {
     Fstab fstab;
     if (!ReadFstabFromDt(&fstab)) {
         if (ReadDefaultFstab(&fstab)) {
@@ -170,7 +172,7 @@
                                        }),
                         fstab.end());
         } else {
-            LOG(INFO) << "Failed to fstab for first stage mount";
+            return Error() << "failed to read default fstab for first stage mount";
         }
     }
     return fstab;
@@ -236,12 +238,16 @@
     super_partition_name_ = fs_mgr_get_super_partition_name();
 }
 
-std::unique_ptr<FirstStageMount> FirstStageMount::Create() {
+Result<std::unique_ptr<FirstStageMount>> FirstStageMount::Create() {
     auto fstab = ReadFirstStageFstab();
-    if (IsDtVbmetaCompatible(fstab)) {
-        return std::make_unique<FirstStageMountVBootV2>(std::move(fstab));
+    if (!fstab.ok()) {
+        return fstab.error();
+    }
+
+    if (IsDtVbmetaCompatible(*fstab)) {
+        return std::make_unique<FirstStageMountVBootV2>(std::move(*fstab));
     } else {
-        return std::make_unique<FirstStageMountVBootV1>(std::move(fstab));
+        return std::make_unique<FirstStageMountVBootV1>(std::move(*fstab));
     }
 }
 
@@ -836,12 +842,12 @@
 // ----------------
 // Creates devices and logical partitions from storage devices
 bool DoCreateDevices() {
-    std::unique_ptr<FirstStageMount> handle = FirstStageMount::Create();
-    if (!handle) {
-        LOG(ERROR) << "Failed to create FirstStageMount";
+    auto fsm = FirstStageMount::Create();
+    if (!fsm.ok()) {
+        LOG(ERROR) << "Failed to create FirstStageMount: " << fsm.error();
         return false;
     }
-    return handle->DoCreateDevices();
+    return (*fsm)->DoCreateDevices();
 }
 
 // Mounts partitions specified by fstab in device tree.
@@ -852,17 +858,17 @@
         return true;
     }
 
-    std::unique_ptr<FirstStageMount> handle = FirstStageMount::Create();
-    if (!handle) {
-        LOG(ERROR) << "Failed to create FirstStageMount";
+    auto fsm = FirstStageMount::Create();
+    if (!fsm.ok()) {
+        LOG(ERROR) << "Failed to create FirstStageMount " << fsm.error();
         return false;
     }
 
     if (create_devices) {
-        if (!handle->DoCreateDevices()) return false;
+        if (!(*fsm)->DoCreateDevices()) return false;
     }
 
-    return handle->DoFirstStageMount();
+    return (*fsm)->DoFirstStageMount();
 }
 
 void SetInitAvbVersionInRecovery() {
@@ -872,8 +878,12 @@
     }
 
     auto fstab = ReadFirstStageFstab();
+    if (!fstab.ok()) {
+        LOG(ERROR) << fstab.error();
+        return;
+    }
 
-    if (!IsDtVbmetaCompatible(fstab)) {
+    if (!IsDtVbmetaCompatible(*fstab)) {
         LOG(INFO) << "Skipped setting INIT_AVB_VERSION (not vbmeta compatible)";
         return;
     }
@@ -883,7 +893,7 @@
     // We only set INIT_AVB_VERSION when the AVB verification succeeds, i.e., the
     // Open() function returns a valid handle.
     // We don't need to mount partitions here in recovery mode.
-    FirstStageMountVBootV2 avb_first_mount(std::move(fstab));
+    FirstStageMountVBootV2 avb_first_mount(std::move(*fstab));
     if (!avb_first_mount.InitDevices()) {
         LOG(ERROR) << "Failed to init devices for INIT_AVB_VERSION";
         return;
diff --git a/init/lmkd_service.cpp b/init/lmkd_service.cpp
index dd1ab4d..c982925 100644
--- a/init/lmkd_service.cpp
+++ b/init/lmkd_service.cpp
@@ -79,7 +79,7 @@
 }
 
 static void RegisterServices(pid_t exclude_pid) {
-    for (const auto& service : ServiceList::GetInstance().services()) {
+    for (const auto& service : ServiceList::GetInstance()) {
         auto svc = service.get();
         if (svc->oom_score_adjust() != DEFAULT_OOM_SCORE_ADJUST) {
             // skip if process is excluded or not yet forked (pid==0)
diff --git a/init/mount_namespace.cpp b/init/mount_namespace.cpp
index ec48cde..15252a6 100644
--- a/init/mount_namespace.cpp
+++ b/init/mount_namespace.cpp
@@ -301,5 +301,20 @@
     return {};
 }
 
+base::Result<MountNamespace> GetCurrentMountNamespace() {
+    std::string current_namespace_id = GetMountNamespaceId();
+    if (current_namespace_id == "") {
+        return Error() << "Failed to get current mount namespace ID";
+    }
+
+    if (current_namespace_id == bootstrap_ns_id) {
+        return NS_BOOTSTRAP;
+    } else if (current_namespace_id == default_ns_id) {
+        return NS_DEFAULT;
+    }
+
+    return Error() << "Failed to find current mount namespace";
+}
+
 }  // namespace init
 }  // namespace android
diff --git a/init/mount_namespace.h b/init/mount_namespace.h
index d4d6f82..5e3dab2 100644
--- a/init/mount_namespace.h
+++ b/init/mount_namespace.h
@@ -26,5 +26,7 @@
 bool SetupMountNamespaces();
 base::Result<void> SwitchToMountNamespaceIfNeeded(MountNamespace target_mount_namespace);
 
+base::Result<MountNamespace> GetCurrentMountNamespace();
+
 }  // namespace init
 }  // namespace android
diff --git a/init/reboot.cpp b/init/reboot.cpp
index e3aaa38..d9acee5 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -85,12 +85,11 @@
 
 static const std::set<std::string> kDebuggingServices{"tombstoned", "logd", "adbd", "console"};
 
-static std::vector<Service*> GetDebuggingServices(bool only_post_data) {
-    std::vector<Service*> ret;
-    ret.reserve(kDebuggingServices.size());
+static std::set<std::string> GetPostDataDebuggingServices() {
+    std::set<std::string> ret;
     for (const auto& s : ServiceList::GetInstance()) {
-        if (kDebuggingServices.count(s->name()) && (!only_post_data || s->is_post_data())) {
-            ret.push_back(s.get());
+        if (kDebuggingServices.count(s->name()) && s->is_post_data()) {
+            ret.insert(s->name());
         }
     }
     return ret;
@@ -503,13 +502,18 @@
 
 // Stops given services, waits for them to be stopped for |timeout| ms.
 // If terminate is true, then SIGTERM is sent to services, otherwise SIGKILL is sent.
-static void StopServices(const std::vector<Service*>& services, std::chrono::milliseconds timeout,
+// Note that services are stopped in order given by |ServiceList::services_in_shutdown_order|
+// function.
+static void StopServices(const std::set<std::string>& services, std::chrono::milliseconds timeout,
                          bool terminate) {
     LOG(INFO) << "Stopping " << services.size() << " services by sending "
               << (terminate ? "SIGTERM" : "SIGKILL");
     std::vector<pid_t> pids;
     pids.reserve(services.size());
-    for (const auto& s : services) {
+    for (const auto& s : ServiceList::GetInstance().services_in_shutdown_order()) {
+        if (services.count(s->name()) == 0) {
+            continue;
+        }
         if (s->pid() > 0) {
             pids.push_back(s->pid());
         }
@@ -529,12 +533,12 @@
 
 // Like StopServices, but also logs all the services that failed to stop after the provided timeout.
 // Returns number of violators.
-static int StopServicesAndLogViolations(const std::vector<Service*>& services,
+static int StopServicesAndLogViolations(const std::set<std::string>& services,
                                         std::chrono::milliseconds timeout, bool terminate) {
     StopServices(services, timeout, terminate);
     int still_running = 0;
-    for (const auto& s : services) {
-        if (s->IsRunning()) {
+    for (const auto& s : ServiceList::GetInstance()) {
+        if (s->IsRunning() && services.count(s->name())) {
             LOG(ERROR) << "[service-misbehaving] : service '" << s->name() << "' is still running "
                        << timeout.count() << "ms after receiving "
                        << (terminate ? "SIGTERM" : "SIGKILL");
@@ -620,8 +624,7 @@
 
     // watchdogd is a vendor specific component but should be alive to complete shutdown safely.
     const std::set<std::string> to_starts{"watchdogd"};
-    std::vector<Service*> stop_first;
-    stop_first.reserve(ServiceList::GetInstance().services().size());
+    std::set<std::string> stop_first;
     for (const auto& s : ServiceList::GetInstance()) {
         if (kDebuggingServices.count(s->name())) {
             // keep debugging tools until non critical ones are all gone.
@@ -639,7 +642,7 @@
                            << "': " << result.error();
             }
         } else {
-            stop_first.push_back(s.get());
+            stop_first.insert(s->name());
         }
     }
 
@@ -703,7 +706,7 @@
         LOG(INFO) << "vold not running, skipping vold shutdown";
     }
     // logcat stopped here
-    StopServices(GetDebuggingServices(false /* only_post_data */), 0ms, false /* SIGKILL */);
+    StopServices(kDebuggingServices, 0ms, false /* SIGKILL */);
     // 4. sync, try umount, and optionally run fsck for user shutdown
     {
         Timer sync_timer;
@@ -785,17 +788,17 @@
         sub_reason = "resetprop";
         return Error() << "Failed to reset sys.powerctl property";
     }
-    std::vector<Service*> stop_first;
+    std::set<std::string> stop_first;
     // Remember the services that were enabled. We will need to manually enable them again otherwise
     // triggers like class_start won't restart them.
-    std::vector<Service*> were_enabled;
-    stop_first.reserve(ServiceList::GetInstance().services().size());
+    std::set<std::string> were_enabled;
     for (const auto& s : ServiceList::GetInstance().services_in_shutdown_order()) {
         if (s->is_post_data() && !kDebuggingServices.count(s->name())) {
-            stop_first.push_back(s);
+            stop_first.insert(s->name());
         }
+        // TODO(ioffe): we should also filter out temporary services here.
         if (s->is_post_data() && s->IsEnabled()) {
-            were_enabled.push_back(s);
+            were_enabled.insert(s->name());
         }
     }
     {
@@ -815,8 +818,8 @@
         r > 0) {
         auto fd = unique_fd(TEMP_FAILURE_RETRY(open(services_file_name.c_str(), flags, 0666)));
         android::base::WriteStringToFd("Post-data services still running: \n", fd);
-        for (const auto& s : stop_first) {
-            if (s->IsRunning()) {
+        for (const auto& s : ServiceList::GetInstance()) {
+            if (s->IsRunning() && stop_first.count(s->name())) {
                 android::base::WriteStringToFd(s->name() + "\n", fd);
             }
         }
@@ -831,13 +834,14 @@
         sub_reason = "vold_reset";
         return result;
     }
-    if (int r = StopServicesAndLogViolations(GetDebuggingServices(true /* only_post_data */),
-                                             sigkill_timeout, false /* SIGKILL */);
+    const auto& debugging_services = GetPostDataDebuggingServices();
+    if (int r = StopServicesAndLogViolations(debugging_services, sigkill_timeout,
+                                             false /* SIGKILL */);
         r > 0) {
         auto fd = unique_fd(TEMP_FAILURE_RETRY(open(services_file_name.c_str(), flags, 0666)));
         android::base::WriteStringToFd("Debugging services still running: \n", fd);
-        for (const auto& s : GetDebuggingServices(true)) {
-            if (s->IsRunning()) {
+        for (const auto& s : ServiceList::GetInstance()) {
+            if (s->IsRunning() && debugging_services.count(s->name())) {
                 android::base::WriteStringToFd(s->name() + "\n", fd);
             }
         }
@@ -867,9 +871,11 @@
         return false;
     });
     // Re-enable services
-    for (const auto& s : were_enabled) {
-        LOG(INFO) << "Re-enabling service '" << s->name() << "'";
-        s->Enable();
+    for (const auto& s : ServiceList::GetInstance()) {
+        if (were_enabled.count(s->name())) {
+            LOG(INFO) << "Re-enabling service '" << s->name() << "'";
+            s->Enable();
+        }
     }
     ServiceList::GetInstance().ResetState();
     LeaveShutdown();
diff --git a/init/service.cpp b/init/service.cpp
index cfb8284..836dc47 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -125,11 +125,6 @@
     return execv(c_strings[0], c_strings.data()) == 0;
 }
 
-static bool AreRuntimeApexesReady() {
-    struct stat buf;
-    return stat("/apex/com.android.runtime/", &buf) == 0;
-}
-
 unsigned long Service::next_start_order_ = 1;
 bool Service::is_exec_service_running_ = false;
 
@@ -312,7 +307,7 @@
 #else
     static bool is_apex_updatable = false;
 #endif
-    const bool is_process_updatable = !pre_apexd_ && is_apex_updatable;
+    const bool is_process_updatable = !use_bootstrap_ns_ && is_apex_updatable;
 
     // If we crash > 4 times in 'fatal_crash_window_' minutes or before boot_completed,
     // reboot into bootloader or set crashing property
@@ -465,12 +460,12 @@
         scon = *result;
     }
 
-    if (!AreRuntimeApexesReady() && !pre_apexd_) {
-        // If this service is started before the Runtime and ART APEXes get
-        // available, mark it as pre-apexd one. Note that this marking is
+    if (!IsDefaultMountNamespaceReady() && name_ != "apexd") {
+        // If this service is started before APEXes and corresponding linker configuration
+        // get available, mark it as pre-apexd one. Note that this marking is
         // permanent. So for example, if the service is re-launched (e.g., due
         // to crash), it is still recognized as pre-apexd... for consistency.
-        pre_apexd_ = true;
+        use_bootstrap_ns_ = true;
     }
 
     // For pre-apexd services, override mount namespace as "bootstrap" one before starting.
@@ -479,7 +474,7 @@
     std::optional<MountNamespace> override_mount_namespace;
     if (name_ == "ueventd") {
         override_mount_namespace = NS_DEFAULT;
-    } else if (pre_apexd_) {
+    } else if (use_bootstrap_ns_) {
         override_mount_namespace = NS_BOOTSTRAP;
     }
 
diff --git a/init/service.h b/init/service.h
index aee1e5d..043555f 100644
--- a/init/service.h
+++ b/init/service.h
@@ -207,7 +207,7 @@
 
     std::vector<std::function<void(const siginfo_t& siginfo)>> reap_callbacks_;
 
-    bool pre_apexd_ = false;
+    bool use_bootstrap_ns_ = false;
 
     bool post_data_ = false;
 
diff --git a/init/service_list.h b/init/service_list.h
index 3b9018b..555da25 100644
--- a/init/service_list.h
+++ b/init/service_list.h
@@ -66,7 +66,6 @@
 
     auto begin() const { return services_.begin(); }
     auto end() const { return services_.end(); }
-    const std::vector<std::unique_ptr<Service>>& services() const { return services_; }
     const std::vector<Service*> services_in_shutdown_order() const;
 
     void MarkPostData();
diff --git a/init/snapuserd_transition.cpp b/init/snapuserd_transition.cpp
index 19b5c57..40467b7 100644
--- a/init/snapuserd_transition.cpp
+++ b/init/snapuserd_transition.cpp
@@ -24,6 +24,7 @@
 
 #include <filesystem>
 #include <string>
+#include <string_view>
 
 #include <android-base/file.h>
 #include <android-base/logging.h>
@@ -34,6 +35,7 @@
 #include <libsnapshot/snapshot.h>
 #include <libsnapshot/snapuserd_client.h>
 #include <private/android_filesystem_config.h>
+#include <procinfo/process_map.h>
 #include <selinux/android.h>
 
 #include "block_dev_initializer.h"
@@ -157,6 +159,33 @@
     });
 }
 
+static void LockAllSystemPages() {
+    bool ok = true;
+    auto callback = [&](const android::procinfo::MapInfo& map) -> void {
+        if (!ok || android::base::StartsWith(map.name, "/dev/") ||
+            !android::base::StartsWith(map.name, "/")) {
+            return;
+        }
+        auto start = reinterpret_cast<const void*>(map.start);
+        auto len = map.end - map.start;
+        if (!len) {
+            return;
+        }
+        if (mlock(start, len) < 0) {
+            LOG(ERROR) << "mlock failed, " << start << " for " << len << " bytes.";
+            ok = false;
+        }
+    };
+
+    if (!android::procinfo::ReadProcessMaps(getpid(), callback) || !ok) {
+        LOG(FATAL) << "Could not process /proc/" << getpid() << "/maps file for init, "
+                   << "falling back to mlockall().";
+        if (mlockall(MCL_CURRENT) < 0) {
+            LOG(FATAL) << "mlockall failed";
+        }
+    }
+}
+
 void SnapuserdSelinuxHelper::StartTransition() {
     LOG(INFO) << "Starting SELinux transition of snapuserd";
 
@@ -170,9 +199,7 @@
 
     // We cannot access /system after the transition, so make sure init is
     // pinned in memory.
-    if (mlockall(MCL_CURRENT) < 0) {
-        LOG(FATAL) << "mlockall failed";
-    }
+    LockAllSystemPages();
 
     argv_.emplace_back("snapuserd");
     argv_.emplace_back("-no_socket");
diff --git a/init/test_utils/service_utils.cpp b/init/test_utils/service_utils.cpp
index ae68679..6426ed9 100644
--- a/init/test_utils/service_utils.cpp
+++ b/init/test_utils/service_utils.cpp
@@ -44,7 +44,7 @@
     }
 
     ServiceInterfacesMap result;
-    for (const auto& service : service_list.services()) {
+    for (const auto& service : service_list) {
         // Create an entry for all services, including services that may not
         // have any declared interfaces.
         result[service->name()] = service->interfaces();
diff --git a/init/util.cpp b/init/util.cpp
index e69b43f..eab99d4 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -735,5 +735,16 @@
     return access("/system/bin/recovery", F_OK) == 0;
 }
 
+// Check if default mount namespace is ready to be used with APEX modules
+static bool is_default_mount_namespace_ready = false;
+
+bool IsDefaultMountNamespaceReady() {
+    return is_default_mount_namespace_ready;
+}
+
+void SetDefaultMountNamespaceReady() {
+    is_default_mount_namespace_ready = true;
+}
+
 }  // namespace init
 }  // namespace android
diff --git a/init/util.h b/init/util.h
index 7745d77..daba852 100644
--- a/init/util.h
+++ b/init/util.h
@@ -100,5 +100,8 @@
 void SetStdioToDevNull(char** argv);
 void InitKernelLogging(char** argv);
 bool IsRecoveryMode();
+
+bool IsDefaultMountNamespaceReady();
+void SetDefaultMountNamespaceReady();
 }  // namespace init
 }  // namespace android
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index 1bf84b4..b38818a 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -1,44 +1,14 @@
-//
-// Copyright (C) 2008 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.
-//
-
 package {
     default_applicable_licenses: ["system_core_libcutils_license"],
 }
 
-// Added automatically by a large-scale-change that took the approach of
-// 'apply every license found to every target'. While this makes sure we respect
-// every license restriction, it may not be entirely correct.
-//
-// e.g. GPL in an MIT project might only apply to the contrib/ directory.
-//
-// Please consider splitting the single license below into multiple licenses,
-// taking care not to lose any license_kind information, and overriding the
-// default license using the 'licenses: [...]' property on targets as needed.
-//
-// For unused files, consider creating a 'fileGroup' with "//visibility:private"
-// to attach the license to, and including a comment whether the files may be
-// used in the current project.
-// See: http://go/android-license-faq
 license {
     name: "system_core_libcutils_license",
     visibility: [":__subpackages__"],
     license_kinds: [
         "SPDX-license-identifier-Apache-2.0",
         "SPDX-license-identifier-BSD",
-        "SPDX-license-identifier-MIT",
+        "SPDX-license-identifier-MIT", // strlcpy.c
     ],
     license_text: [
         "NOTICE",
@@ -50,30 +20,32 @@
     srcs: ["include/private/android_filesystem_config.h"],
 }
 
-// some files must not be compiled when building against Mingw
-// they correspond to features not used by our host development tools
-// which are also hard or even impossible to port to native Win32
-libcutils_nonwindows_sources = [
-    "fs.cpp",
-    "hashmap.cpp",
-    "multiuser.cpp",
-    "str_parms.cpp",
-]
+cc_defaults {
+    name: "libcutils_defaults",
+    cflags: [
+        "-Wno-exit-time-destructors",
+    ],
 
-cc_library_headers {
-    name: "libcutils_headers",
-    vendor_available: true,
     product_available: true,
-    recovery_available: true,
     ramdisk_available: true,
+    recovery_available: true,
+    vendor_available: true,
     vendor_ramdisk_available: true,
+
     host_supported: true,
+    native_bridge_supported: true,
+
     apex_available: [
         "//apex_available:platform",
         "//apex_available:anyapex",
     ],
     min_sdk_version: "29",
-    native_bridge_supported: true,
+}
+
+cc_library_headers {
+    name: "libcutils_headers",
+    defaults: ["libcutils_defaults"],
+
     export_include_dirs: ["include"],
     target: {
         vendor: {
@@ -94,18 +66,7 @@
 // Socket specific parts of libcutils that are safe to statically link into an APEX.
 cc_library {
     name: "libcutils_sockets",
-    vendor_available: true,
-    product_available: true,
-    recovery_available: true,
-    ramdisk_available: true,
-    vendor_ramdisk_available: true,
-    host_supported: true,
-    native_bridge_supported: true,
-    apex_available: [
-        "//apex_available:platform",
-        "//apex_available:anyapex",
-    ],
-    min_sdk_version: "29",
+    defaults: ["libcutils_defaults"],
 
     export_include_dirs: ["include"],
 
@@ -176,23 +137,23 @@
     },
 }
 
+// some files must not be compiled when building against Mingw
+// they correspond to features not used by our host development tools
+// which are also hard or even impossible to port to native Win32
+libcutils_nonwindows_sources = [
+    "fs.cpp",
+    "hashmap.cpp",
+    "multiuser.cpp",
+    "str_parms.cpp",
+]
+
 cc_library {
     name: "libcutils",
-    vendor_available: true,
-    product_available: true,
+    defaults: ["libcutils_defaults"],
     vndk: {
         enabled: true,
         support_system_process: true,
     },
-    recovery_available: true,
-    vendor_ramdisk_available: true,
-    host_supported: true,
-    apex_available: [
-        "//apex_available:platform",
-        "//apex_available:anyapex",
-    ],
-    min_sdk_version: "29",
-    native_bridge_supported: true,
     srcs: [
         "config_utils.cpp",
         "canned_fs_config.cpp",
@@ -209,10 +170,14 @@
         linux_bionic: {
             enabled: true,
         },
+        linux: {
+            srcs: [
+                "fs_config.cpp",
+            ],
+        },
         not_windows: {
             srcs: libcutils_nonwindows_sources + [
                 "ashmem-host.cpp",
-                "fs_config.cpp",
                 "trace-host.cpp",
             ],
         },
@@ -232,7 +197,6 @@
             srcs: libcutils_nonwindows_sources + [
                 "android_reboot.cpp",
                 "ashmem-dev.cpp",
-                "fs_config.cpp",
                 "klog.cpp",
                 "partition_utils.cpp",
                 "qtaguid.cpp",
@@ -290,7 +254,6 @@
     header_libs: [
         "libbase_headers",
         "libcutils_headers",
-        "libutils_headers",
         "libprocessgroup_headers",
     ],
     export_header_lib_headers: [
diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp
index 79c3abc..54eeeac 100644
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -37,7 +37,6 @@
 #include <android-base/strings.h>
 #include <log/log.h>
 #include <private/android_filesystem_config.h>
-#include <utils/Compat.h>
 
 #include "fs_config.h"
 
diff --git a/libcutils/include/cutils/threads.h b/libcutils/include/cutils/threads.h
index 0f7f8a8..0082c6c 100644
--- a/libcutils/include/cutils/threads.h
+++ b/libcutils/include/cutils/threads.h
@@ -31,7 +31,9 @@
 //
 // Deprecated: use android::base::GetThreadId instead, which doesn't truncate on Mac/Windows.
 //
+#if !defined(__GLIBC__) || __GLIBC__ >= 2 && __GLIBC_MINOR__ < 32
 extern pid_t gettid();
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/libcutils/threads.cpp b/libcutils/threads.cpp
index 8cfee1e..6ece7a3 100644
--- a/libcutils/threads.cpp
+++ b/libcutils/threads.cpp
@@ -25,8 +25,9 @@
 #include <windows.h>
 #endif
 
-#if defined(__BIONIC__)
+#if defined(__BIONIC__) || defined(__GLIBC__) && __GLIBC_MINOR__ >= 32
 // No definition needed for Android because we'll just pick up bionic's copy.
+// No definition needed for Glibc >= 2.32 because it exposes its own copy.
 #else
 pid_t gettid() {
 #if defined(__APPLE__)
diff --git a/libprocessgroup/include/processgroup/processgroup.h b/libprocessgroup/include/processgroup/processgroup.h
index f826e9c..fa2642d 100644
--- a/libprocessgroup/include/processgroup/processgroup.h
+++ b/libprocessgroup/include/processgroup/processgroup.h
@@ -35,10 +35,6 @@
 #ifndef __ANDROID_VNDK__
 
 static constexpr const char* CGROUPS_RC_PATH = "/dev/cgroup_info/cgroup.rc";
-// Path to test against for freezer support
-// TODO: remove it once https://r.android.com/1607196 is properly merged to all branches,
-// see http://b/180056337
-static constexpr const char* CGROUP_FREEZE_PATH = "/sys/fs/cgroup/uid_0/cgroup.freeze";
 
 bool UsePerAppMemcg();
 
diff --git a/libprocessgroup/setup/cgroup_map_write.cpp b/libprocessgroup/setup/cgroup_map_write.cpp
index 753fd2d..aa41acb 100644
--- a/libprocessgroup/setup/cgroup_map_write.cpp
+++ b/libprocessgroup/setup/cgroup_map_write.cpp
@@ -183,10 +183,12 @@
         return false;
     }
 
-    Json::Reader reader;
+    Json::CharReaderBuilder builder;
+    std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
     Json::Value root;
-    if (!reader.parse(json_doc, root)) {
-        LOG(ERROR) << "Failed to parse cgroups description: " << reader.getFormattedErrorMessages();
+    std::string errorMessage;
+    if (!reader->parse(&*json_doc.begin(), &*json_doc.end(), &root, &errorMessage)) {
+        LOG(ERROR) << "Failed to parse cgroups description: " << errorMessage;
         return false;
     }
 
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index 8d4ce25..f13a681 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -425,10 +425,12 @@
         return false;
     }
 
-    Json::Reader reader;
+    Json::CharReaderBuilder builder;
+    std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
     Json::Value root;
-    if (!reader.parse(json_doc, root)) {
-        LOG(ERROR) << "Failed to parse task profiles: " << reader.getFormattedErrorMessages();
+    std::string errorMessage;
+    if (!reader->parse(&*json_doc.begin(), &*json_doc.end(), &root, &errorMessage)) {
+        LOG(ERROR) << "Failed to parse task profiles: " << errorMessage;
         return false;
     }
 
diff --git a/libutils/Android.bp b/libutils/Android.bp
index c9ecfa9..6201569 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -1,23 +1,7 @@
-// Copyright (C) 2008 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.
-
 package {
     default_applicable_licenses: ["system_core_libutils_license"],
 }
 
-// Added automatically by a large-scale-change
-// See: http://go/android-license-faq
 license {
     name: "system_core_libutils_license",
     visibility: [":__subpackages__"],
@@ -91,6 +75,7 @@
     cflags: [
         "-Wall",
         "-Werror",
+        "-Wno-exit-time-destructors",
     ],
     header_libs: [
         "libbase_headers",
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 995b1c5..0e1e98b 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -471,6 +471,9 @@
     chmod 0664 /sys/module/lowmemorykiller/parameters/minfree
     start lmkd
 
+    # Set an initial boot level - start at 10 in case we need to add earlier ones.
+    setprop keystore.boot_level 10
+
     # Start essential services.
     start servicemanager
     start hwservicemanager
@@ -617,6 +620,15 @@
     # Load trusted keys from dm-verity protected partitions
     exec -- /system/bin/fsverity_init --load-verified-keys
 
+    # Set up a tracing instance for system_server to monitor error_report_end events.
+    # These are sent by kernel tools like KASAN and KFENCE when a memory corruption
+    # is detected.
+    mkdir /sys/kernel/tracing/instances/bootreceiver 0700 system system
+    restorecon_recursive /sys/kernel/tracing/instances/bootreceiver
+    write /sys/kernel/tracing/instances/bootreceiver/buffer_size_kb 1
+    write /sys/kernel/tracing/instances/bootreceiver/trace_options disable_on_free
+    write /sys/kernel/tracing/instances/bootreceiver/events/error_report/error_report_end/enable 1
+
 on post-fs-data
     mark_post_data
 
diff --git a/trusty/apploader/fuzz/Android.bp b/trusty/apploader/fuzz/Android.bp
new file mode 100644
index 0000000..e37dab1
--- /dev/null
+++ b/trusty/apploader/fuzz/Android.bp
@@ -0,0 +1,40 @@
+// Copyright (C) 2021 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+// Fuzz Trusty IPC messages sent to apploader.
+cc_fuzz {
+    name: "trusty_apploader_tipc_fuzzer",
+    defaults: ["trusty_fuzzer_defaults"],
+    srcs: [":trusty_tipc_fuzzer"],
+    cflags: [
+        "-DTRUSTY_APP_PORT=\"com.android.trusty.apploader\"",
+        "-DTRUSTY_APP_UUID=\"081ba88f-f1ee-452e-b5e8-a7e9ef173a97\"",
+        "-DTRUSTY_APP_FILENAME=\"apploader.syms.elf\"",
+    ]
+}
+
+// Fuzz app package sent to apploader.
+cc_fuzz {
+    name: "trusty_apploader_app_fuzzer",
+    defaults: ["trusty_fuzzer_defaults"],
+    srcs: ["app_fuzzer.cpp"],
+    include_dirs: ["system/core/trusty/apploader"],
+    shared_libs: [
+        "libdmabufheap",
+    ],
+}
diff --git a/trusty/apploader/fuzz/app_fuzzer.cpp b/trusty/apploader/fuzz/app_fuzzer.cpp
new file mode 100644
index 0000000..aa0caca
--- /dev/null
+++ b/trusty/apploader/fuzz/app_fuzzer.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2021 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 <BufferAllocator/BufferAllocator.h>
+#include <android-base/unique_fd.h>
+#include <apploader_ipc.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <trusty/coverage/coverage.h>
+#include <trusty/fuzz/counters.h>
+#include <trusty/fuzz/utils.h>
+#include <trusty/tipc.h>
+#include <unistd.h>
+#include <iostream>
+
+using android::base::unique_fd;
+using android::trusty::coverage::CoverageRecord;
+using android::trusty::fuzz::ExtraCounters;
+using android::trusty::fuzz::TrustyApp;
+
+#define TIPC_DEV "/dev/trusty-ipc-dev0"
+#define APPLOADER_PORT "com.android.trusty.apploader"
+#define APPLOADER_MODULE_NAME "apploader.syms.elf"
+
+/* Apploader TA's UUID is 081ba88f-f1ee-452e-b5e8-a7e9ef173a97 */
+static struct uuid apploader_uuid = {
+        0x081ba88f,
+        0xf1ee,
+        0x452e,
+        {0xb5, 0xe8, 0xa7, 0xe9, 0xef, 0x17, 0x3a, 0x97},
+};
+
+static inline uintptr_t RoundPageUp(uintptr_t val) {
+    return (val + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
+}
+
+static bool SendLoadMsg(int chan, int dma_buf, size_t dma_buf_size) {
+    apploader_header hdr = {
+            .cmd = APPLOADER_CMD_LOAD_APPLICATION,
+    };
+    apploader_load_app_req req = {
+            .package_size = static_cast<uint64_t>(dma_buf_size),
+    };
+    iovec iov[] = {
+            {
+                    .iov_base = &hdr,
+                    .iov_len = sizeof(hdr),
+            },
+            {
+                    .iov_base = &req,
+                    .iov_len = sizeof(req),
+            },
+    };
+    trusty_shm shm = {
+            .fd = dma_buf,
+            .transfer = TRUSTY_SHARE,
+    };
+
+    int rc = tipc_send(chan, iov, 2, &shm, 1);
+    if (rc != static_cast<int>(sizeof(hdr) + sizeof(req))) {
+        std::cerr << "Failed to send request" << std::endl;
+        return false;
+    }
+
+    apploader_resp resp;
+    rc = read(chan, &resp, sizeof(resp));
+    if (rc != static_cast<int>(sizeof(resp))) {
+        std::cerr << "Failed to receive response" << std::endl;
+        return false;
+    }
+
+    return true;
+}
+
+static CoverageRecord record(TIPC_DEV, &apploader_uuid, APPLOADER_MODULE_NAME);
+
+extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
+    auto ret = record.Open();
+    if (!ret.ok()) {
+        std::cerr << ret.error() << std::endl;
+        exit(-1);
+    }
+    return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    ExtraCounters counters(&record);
+    counters.Reset();
+
+    android::trusty::fuzz::TrustyApp ta(TIPC_DEV, APPLOADER_PORT);
+    auto ret = ta.Connect();
+    if (!ret.ok()) {
+        std::cerr << ret.error() << std::endl;
+        android::trusty::fuzz::Abort();
+    }
+
+    uint64_t shm_len = size ? RoundPageUp(size) : PAGE_SIZE;
+    BufferAllocator alloc;
+    unique_fd dma_buf(alloc.Alloc(kDmabufSystemHeapName, shm_len));
+    if (dma_buf < 0) {
+        std::cerr << "Failed to create dmabuf of size: " << shm_len << std::endl;
+        android::trusty::fuzz::Abort();
+    }
+
+    void* shm_base = mmap(0, shm_len, PROT_READ | PROT_WRITE, MAP_SHARED, dma_buf, 0);
+    if (shm_base == MAP_FAILED) {
+        std::cerr << "Failed to mmap() dmabuf" << std::endl;
+        android::trusty::fuzz::Abort();
+    }
+
+    memcpy(shm_base, data, size);
+
+    bool success = SendLoadMsg(*ta.GetRawFd(), dma_buf, shm_len);
+    if (!success) {
+        std::cerr << "Failed to send load message" << std::endl;
+        android::trusty::fuzz::Abort();
+    }
+
+    munmap(shm_base, shm_len);
+    return 0;
+}
diff --git a/trusty/confirmationui/TrustyApp.cpp b/trusty/confirmationui/TrustyApp.cpp
index 1e70a5e..cee8655 100644
--- a/trusty/confirmationui/TrustyApp.cpp
+++ b/trusty/confirmationui/TrustyApp.cpp
@@ -15,7 +15,6 @@
  */
 
 #include "TrustyApp.h"
-#include "TrustyIpc.h"
 
 #include <BufferAllocator/BufferAllocator.h>
 #include <android-base/logging.h>
@@ -27,6 +26,7 @@
 
 namespace android {
 namespace trusty {
+namespace confirmationui {
 
 using ::android::base::unique_fd;
 
@@ -162,5 +162,6 @@
     LOG(INFO) << "Done shutting down TrustyApp";
 }
 
+}  // namespace confirmationui
 }  // namespace trusty
 }  // namespace android
diff --git a/trusty/confirmationui/TrustyApp.h b/trusty/confirmationui/TrustyApp.h
index 406f439..fb57828 100644
--- a/trusty/confirmationui/TrustyApp.h
+++ b/trusty/confirmationui/TrustyApp.h
@@ -16,7 +16,7 @@
 
 #pragma once
 
-#include "TrustyIpc.h"
+#include <TrustyIpc.h>
 
 #include <android-base/logging.h>
 #include <android-base/unique_fd.h>
@@ -41,6 +41,7 @@
 
 namespace android {
 namespace trusty {
+namespace confirmationui {
 
 using ::teeui::Message;
 using ::teeui::msg2tuple_t;
@@ -148,5 +149,6 @@
     operator bool() const { return handle_ != kInvalidHandle; }
 };
 
+}  // namespace confirmationui
 }  // namespace trusty
 }  // namespace android
diff --git a/trusty/confirmationui/TrustyConfirmationUI.cpp b/trusty/confirmationui/TrustyConfirmationUI.cpp
index c8b24e3..c6625e0 100644
--- a/trusty/confirmationui/TrustyConfirmationUI.cpp
+++ b/trusty/confirmationui/TrustyConfirmationUI.cpp
@@ -50,7 +50,7 @@
 
 using namespace secure_input;
 
-using ::android::trusty::TrustyAppError;
+using ::android::trusty::confirmationui::TrustyAppError;
 
 using ::teeui::AbortMsg;
 using ::teeui::DeliverTestCommandMessage;
diff --git a/trusty/confirmationui/TrustyConfirmationUI.h b/trusty/confirmationui/TrustyConfirmationUI.h
index 3a7c7ef..0bd703c 100644
--- a/trusty/confirmationui/TrustyConfirmationUI.h
+++ b/trusty/confirmationui/TrustyConfirmationUI.h
@@ -43,7 +43,7 @@
 using ::android::hardware::Return;
 using ::android::hardware::Void;
 
-using ::android::trusty::TrustyApp;
+using ::android::trusty::confirmationui::TrustyApp;
 
 class TrustyConfirmationUI : public IConfirmationUI {
   public:
diff --git a/trusty/confirmationui/fuzz/Android.bp b/trusty/confirmationui/fuzz/Android.bp
index 12bb70a..ba57191 100644
--- a/trusty/confirmationui/fuzz/Android.bp
+++ b/trusty/confirmationui/fuzz/Android.bp
@@ -17,11 +17,27 @@
 }
 
 cc_fuzz {
-    name: "trusty_confirmationui_fuzzer",
+    name: "trusty_confirmationui_tipc_fuzzer",
     defaults: ["trusty_fuzzer_defaults"],
-    srcs: ["fuzz.cpp"],
+    srcs: [":trusty_tipc_fuzzer"],
+    cflags: [
+        "-DTRUSTY_APP_PORT=\"com.android.trusty.confirmationui\"",
+        "-DTRUSTY_APP_UUID=\"7dee2364-c036-425b-b086-df0f6c233c1b\"",
+        "-DTRUSTY_APP_FILENAME=\"confirmationui.syms.elf\"",
+    ],
 
-    // The initial corpus for this fuzzer was derived by dumping bytes from
-    // ConfirmationUI VTS.
-    corpus: ["corpus/*"],
+}
+
+cc_fuzz {
+    name: "trusty_confirmationui_msg_fuzzer",
+    defaults: ["trusty_fuzzer_defaults"],
+    srcs: ["msg_fuzzer.cpp"],
+    include_dirs: ["system/core/trusty/confirmationui/include"],
+    shared_libs: [
+        "libdmabufheap",
+    ],
+
+    // The initial corpus for this fuzzer was derived by dumping messages from/to
+    // HAL to/from TA triggered by VtsHalConfirmationUIV1_0TargetTest.
+    corpus: ["msg_corpus/*"],
 }
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-2ekYc2 b/trusty/confirmationui/fuzz/corpus/confirmationui-2ekYc2
deleted file mode 100644
index 53fe0c9..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-2ekYc2
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-6l8Soq b/trusty/confirmationui/fuzz/corpus/confirmationui-6l8Soq
deleted file mode 100644
index bda80fd..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-6l8Soq
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-7kFpGO b/trusty/confirmationui/fuzz/corpus/confirmationui-7kFpGO
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-7kFpGO
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-92m2f3 b/trusty/confirmationui/fuzz/corpus/confirmationui-92m2f3
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-92m2f3
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-ALYIzO b/trusty/confirmationui/fuzz/corpus/confirmationui-ALYIzO
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-ALYIzO
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-AcIMhR b/trusty/confirmationui/fuzz/corpus/confirmationui-AcIMhR
deleted file mode 100644
index f5854f8..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-AcIMhR
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-AieaIi b/trusty/confirmationui/fuzz/corpus/confirmationui-AieaIi
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-AieaIi
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-BdqX5j b/trusty/confirmationui/fuzz/corpus/confirmationui-BdqX5j
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-BdqX5j
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-JBPIGs b/trusty/confirmationui/fuzz/corpus/confirmationui-JBPIGs
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-JBPIGs
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-MWHw4T b/trusty/confirmationui/fuzz/corpus/confirmationui-MWHw4T
deleted file mode 100644
index 0dc6e91..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-MWHw4T
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-TZzVLO b/trusty/confirmationui/fuzz/corpus/confirmationui-TZzVLO
deleted file mode 100644
index 927d64d..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-TZzVLO
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-WwdA3B b/trusty/confirmationui/fuzz/corpus/confirmationui-WwdA3B
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-WwdA3B
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-globJV b/trusty/confirmationui/fuzz/corpus/confirmationui-globJV
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-globJV
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-hzUgjD b/trusty/confirmationui/fuzz/corpus/confirmationui-hzUgjD
deleted file mode 100644
index 87870ca..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-hzUgjD
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-jXC78o b/trusty/confirmationui/fuzz/corpus/confirmationui-jXC78o
deleted file mode 100644
index 0b274bf..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-jXC78o
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-kykxni b/trusty/confirmationui/fuzz/corpus/confirmationui-kykxni
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-kykxni
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-npHe8t b/trusty/confirmationui/fuzz/corpus/confirmationui-npHe8t
deleted file mode 100644
index 87870ca..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-npHe8t
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-rPgnyI b/trusty/confirmationui/fuzz/corpus/confirmationui-rPgnyI
deleted file mode 100644
index 87870ca..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-rPgnyI
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-uCJ1Me b/trusty/confirmationui/fuzz/corpus/confirmationui-uCJ1Me
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-uCJ1Me
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-wAQEjK b/trusty/confirmationui/fuzz/corpus/confirmationui-wAQEjK
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-wAQEjK
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-xjtOks b/trusty/confirmationui/fuzz/corpus/confirmationui-xjtOks
deleted file mode 100644
index b4a1c49..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-xjtOks
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-zKFIjN b/trusty/confirmationui/fuzz/corpus/confirmationui-zKFIjN
deleted file mode 100644
index 5adf905..0000000
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-zKFIjN
+++ /dev/null
Binary files differ
diff --git a/trusty/confirmationui/fuzz/fuzz.cpp b/trusty/confirmationui/fuzz/fuzz.cpp
deleted file mode 100644
index df2517c..0000000
--- a/trusty/confirmationui/fuzz/fuzz.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2020 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 <iostream>
-#include <stdlib.h>
-#include <trusty/coverage/coverage.h>
-#include <trusty/fuzz/counters.h>
-#include <trusty/fuzz/utils.h>
-#include <unistd.h>
-
-using android::trusty::coverage::CoverageRecord;
-using android::trusty::fuzz::ExtraCounters;
-using android::trusty::fuzz::TrustyApp;
-
-#define TIPC_DEV "/dev/trusty-ipc-dev0"
-#define CONFIRMATIONUI_PORT "com.android.trusty.confirmationui"
-#define CONFIRMATIONUI_MODULE_NAME "confirmationui.syms.elf"
-
-/* ConfirmationUI TA's UUID is 7dee2364-c036-425b-b086-df0f6c233c1b */
-static struct uuid confirmationui_uuid = {
-    0x7dee2364,
-    0xc036,
-    0x425b,
-    {0xb0, 0x86, 0xdf, 0x0f, 0x6c, 0x23, 0x3c, 0x1b},
-};
-
-/* The format of the packets is as following:
- * 16 bits (uint16_t, header) + payload bytes
- * The 16 bits header spicify the number of bytes of payload (header excluded).
- */
-struct data_packet {
-    uint16_t header;
-    uint8_t payload[];
-};
-
-static CoverageRecord record(TIPC_DEV, &confirmationui_uuid, CONFIRMATIONUI_MODULE_NAME);
-
-extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
-    auto ret = record.Open();
-    if (!ret.ok()) {
-        std::cerr << ret.error() << std::endl;
-        exit(-1);
-    }
-    return 0;
-}
-
-/* Each corpus contains one or more data packets. */
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-    static uint8_t buf[TIPC_MAX_MSG_SIZE];
-    size_t data_idx = 0;
-
-    ExtraCounters counters(&record);
-    counters.Reset();
-
-    TrustyApp ta(TIPC_DEV, CONFIRMATIONUI_PORT);
-    auto ret = ta.Connect();
-    if (!ret.ok()) {
-        android::trusty::fuzz::Abort();
-    }
-
-    while (data_idx < size) {
-        struct data_packet* data_packet_ptr = (struct data_packet*)&data[data_idx];
-        size_t payload_size = data_packet_ptr->header;
-        data_idx += data_packet_ptr->header + sizeof(data_packet_ptr->header);
-
-        /* Write message to confirmationui server */
-        ret = ta.Write(data_packet_ptr->payload, payload_size);
-        if (!ret.ok()) {
-            return -1;
-        }
-
-        /* Read message from confirmationui server */
-        ret = ta.Read(&buf, sizeof(buf));
-        if (!ret.ok()) {
-            return -1;
-        }
-    }
-
-    return 0;
-}
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-0AD0Mc b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-0AD0Mc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-0AD0Mc
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-1b1UIl b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-1b1UIl
new file mode 100644
index 0000000..c8741fb
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-1b1UIl
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-3hmWyl b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-3hmWyl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-3hmWyl
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-7FNOdd b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-7FNOdd
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-7FNOdd
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-7T30a0 b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-7T30a0
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-7T30a0
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-86EumR b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-86EumR
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-86EumR
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-89b64b b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-89b64b
new file mode 100644
index 0000000..1682427
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-89b64b
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-8UVUCK b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-8UVUCK
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-8UVUCK
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-BSmqJ0 b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-BSmqJ0
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-BSmqJ0
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-BdUGLb b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-BdUGLb
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-BdUGLb
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-D2ENNi b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-D2ENNi
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-D2ENNi
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-EwBsPi b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-EwBsPi
new file mode 100644
index 0000000..d48e5a1
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-EwBsPi
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-HjE2Ko b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-HjE2Ko
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-HjE2Ko
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-J5OABY b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-J5OABY
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-J5OABY
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-LUVKQn b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-LUVKQn
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-LUVKQn
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-MdY9ZS b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-MdY9ZS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-MdY9ZS
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-NZ8yUq b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-NZ8yUq
new file mode 100644
index 0000000..6f72ad5
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-NZ8yUq
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-OP4Vff b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-OP4Vff
new file mode 100644
index 0000000..64a159c
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-OP4Vff
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-OizTST b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-OizTST
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-OizTST
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-QTsc3y b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-QTsc3y
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-QTsc3y
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-S055ei b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-S055ei
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-S055ei
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-VDguJL b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-VDguJL
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-VDguJL
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-ZjDqjf b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-ZjDqjf
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-ZjDqjf
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-bMNGfb b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-bMNGfb
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-bMNGfb
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-bm0GEm b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-bm0GEm
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-bm0GEm
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-cT2nt8 b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-cT2nt8
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-cT2nt8
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-e1NLbb b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-e1NLbb
new file mode 100644
index 0000000..64a159c
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-e1NLbb
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-eOCb7t b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-eOCb7t
new file mode 100644
index 0000000..64a159c
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-eOCb7t
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-h7Gpzu b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-h7Gpzu
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-h7Gpzu
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-ikJlIo b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-ikJlIo
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-ikJlIo
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-kxugwp b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-kxugwp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-kxugwp
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-mY8uM5 b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-mY8uM5
new file mode 100644
index 0000000..556828d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-mY8uM5
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-nuYOin b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-nuYOin
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-nuYOin
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-obk0rP b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-obk0rP
new file mode 100644
index 0000000..8be96c5
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-obk0rP
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-vg2hAB b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-vg2hAB
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-vg2hAB
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-ysk3Rj b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-ysk3Rj
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-recv-ysk3Rj
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-2upXHa b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-2upXHa
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-2upXHa
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-3n7SWz b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-3n7SWz
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-3n7SWz
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-5SZG4U b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-5SZG4U
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-5SZG4U
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-8uL1hT b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-8uL1hT
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-8uL1hT
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-Anu8LZ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-Anu8LZ
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-Anu8LZ
Binary files differ
diff --git a/trusty/confirmationui/fuzz/corpus/confirmationui-5yTG3f b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-BFP3vG
similarity index 95%
rename from trusty/confirmationui/fuzz/corpus/confirmationui-5yTG3f
rename to trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-BFP3vG
index d627b01..b944d94 100644
--- a/trusty/confirmationui/fuzz/corpus/confirmationui-5yTG3f
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-BFP3vG
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-BjxIpX b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-BjxIpX
new file mode 100644
index 0000000..1d9374d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-BjxIpX
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-DBzfWz b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-DBzfWz
new file mode 100644
index 0000000..b3be8cd
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-DBzfWz
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-GPOMKC b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-GPOMKC
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-GPOMKC
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-GWcpFn b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-GWcpFn
new file mode 100644
index 0000000..4190adf
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-GWcpFn
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-HkRYSS b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-HkRYSS
new file mode 100644
index 0000000..1d9374d
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-HkRYSS
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-LAyw30 b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-LAyw30
new file mode 100644
index 0000000..38e3fca
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-LAyw30
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-MtGRnC b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-MtGRnC
new file mode 100644
index 0000000..4190adf
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-MtGRnC
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-PpfYNn b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-PpfYNn
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-PpfYNn
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-SVKqZi b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-SVKqZi
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-SVKqZi
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-Suxofv b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-Suxofv
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-Suxofv
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-UQPTAG b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-UQPTAG
new file mode 100644
index 0000000..4190adf
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-UQPTAG
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-Up2pbn b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-Up2pbn
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-Up2pbn
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ZjgVzs b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ZjgVzs
new file mode 100644
index 0000000..cbfd07a
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ZjgVzs
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ZuQuBC b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ZuQuBC
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ZuQuBC
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-bWlzZp b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-bWlzZp
new file mode 100644
index 0000000..ecaec12
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-bWlzZp
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-dPozfE b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-dPozfE
new file mode 100644
index 0000000..58b1526
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-dPozfE
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-e952U6 b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-e952U6
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-e952U6
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-f7ly1r b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-f7ly1r
new file mode 100644
index 0000000..af570ea
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-f7ly1r
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-hme7P0 b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-hme7P0
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-hme7P0
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-k7J5LL b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-k7J5LL
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-k7J5LL
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-rUtYXs b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-rUtYXs
new file mode 100644
index 0000000..e4b99fb
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-rUtYXs
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-sq5ang b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-sq5ang
new file mode 100644
index 0000000..d114956
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-sq5ang
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-uOtedb b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-uOtedb
new file mode 100644
index 0000000..6caf7dd
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-uOtedb
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-vGoOUt b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-vGoOUt
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-vGoOUt
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-vqAG14 b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-vqAG14
new file mode 100644
index 0000000..ecaec12
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-vqAG14
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-xKDdTw b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-xKDdTw
new file mode 100644
index 0000000..36445d9
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-xKDdTw
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-xT4sJC b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-xT4sJC
new file mode 100644
index 0000000..f6c6dcf
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-xT4sJC
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ypshr5 b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ypshr5
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ypshr5
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ypzCDH b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ypzCDH
new file mode 100644
index 0000000..d6ba1fc
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-ypzCDH
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-zZNPRC b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-zZNPRC
new file mode 100644
index 0000000..7392034
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_corpus/confirmationui-send-zZNPRC
Binary files differ
diff --git a/trusty/confirmationui/fuzz/msg_fuzzer.cpp b/trusty/confirmationui/fuzz/msg_fuzzer.cpp
new file mode 100644
index 0000000..8e4443c
--- /dev/null
+++ b/trusty/confirmationui/fuzz/msg_fuzzer.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2021 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 <BufferAllocator/BufferAllocator.h>
+#include <TrustyIpc.h>
+#include <iostream>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <time.h>
+#include <trusty/coverage/coverage.h>
+#include <trusty/fuzz/counters.h>
+#include <trusty/fuzz/utils.h>
+#include <trusty/tipc.h>
+#include <unistd.h>
+
+using android::trusty::coverage::CoverageRecord;
+using android::trusty::fuzz::ExtraCounters;
+using android::trusty::fuzz::TrustyApp;
+
+#define countof(arr) (sizeof(arr) / sizeof(arr[0]))
+
+#define TIPC_DEV "/dev/trusty-ipc-dev0"
+#define CONFIRMATIONUI_PORT "com.android.trusty.confirmationui"
+#define CONFIRMATIONUI_MODULE_NAME "confirmationui.syms.elf"
+
+/* A request to render to screen may take a while. */
+const size_t kTimeoutSeconds = 30;
+
+/* ConfirmationUI TA's UUID is 7dee2364-c036-425b-b086-df0f6c233c1b */
+static struct uuid confirmationui_uuid = {
+    0x7dee2364,
+    0xc036,
+    0x425b,
+    {0xb0, 0x86, 0xdf, 0x0f, 0x6c, 0x23, 0x3c, 0x1b},
+};
+
+static CoverageRecord record(TIPC_DEV, &confirmationui_uuid, CONFIRMATIONUI_MODULE_NAME);
+
+static android::base::unique_fd dma_buf;
+static void* shm_base;
+
+extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
+    auto ret = record.Open();
+    if (!ret.ok()) {
+        std::cerr << ret.error() << std::endl;
+        exit(-1);
+    }
+
+    BufferAllocator allocator;
+    dma_buf.reset(allocator.Alloc(kDmabufSystemHeapName, CONFIRMATIONUI_MAX_MSG_SIZE));
+    if (dma_buf < 0) {
+        std::cerr << "Failed to allocate dma_buf" << std::endl;
+        exit(-1);
+    }
+
+    shm_base = mmap(0, CONFIRMATIONUI_MAX_MSG_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, dma_buf, 0);
+    if (shm_base == MAP_FAILED) {
+        std::cerr << "Failed to mmap() dma_buf" << std::endl;
+        exit(-1);
+    }
+
+    return 0;
+}
+
+static bool Init(int chan, int dma_buf) {
+    confirmationui_hdr hdr = {
+        .cmd = CONFIRMATIONUI_CMD_INIT,
+    };
+    confirmationui_init_req args = {
+        .shm_len = CONFIRMATIONUI_MAX_MSG_SIZE,
+    };
+    iovec iov[] = {
+        {
+            .iov_base = &hdr,
+            .iov_len = sizeof(hdr),
+        },
+        {
+            .iov_base = &args,
+            .iov_len = sizeof(args),
+        },
+    };
+    trusty_shm shm = {
+        .fd = dma_buf,
+        .transfer = TRUSTY_SHARE,
+    };
+
+    int rc = tipc_send(chan, iov, countof(iov), &shm, 1);
+    if (rc != static_cast<int>(sizeof(hdr) + sizeof(args))) {
+        return false;
+    }
+
+    rc = read(chan, &hdr, sizeof(hdr));
+    if (rc != static_cast<int>(sizeof(hdr))) {
+        return false;
+    }
+
+    return true;
+}
+
+static bool Msg(int chan, const uint8_t* data, size_t size) {
+    confirmationui_hdr hdr = {
+        .cmd = CONFIRMATIONUI_CMD_MSG,
+    };
+    confirmationui_msg_args args = {
+        .msg_len = static_cast<uint32_t>(size),
+    };
+    iovec iov[] = {
+        {
+            .iov_base = &hdr,
+            .iov_len = sizeof(hdr),
+        },
+        {
+            .iov_base = &args,
+            .iov_len = sizeof(args),
+        },
+    };
+
+    memset(shm_base, 0, CONFIRMATIONUI_MAX_MSG_SIZE);
+    memcpy(shm_base, data, size);
+
+    int rc = tipc_send(chan, iov, countof(iov), NULL, 0);
+    if (rc != static_cast<int>(sizeof(hdr) + sizeof(args))) {
+        return false;
+    }
+
+    rc = readv(chan, iov, countof(iov));
+    if (rc != static_cast<int>(sizeof(hdr) + sizeof(args))) {
+        return false;
+    }
+
+    return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    ExtraCounters counters(&record);
+    counters.Reset();
+
+    TrustyApp ta(TIPC_DEV, CONFIRMATIONUI_PORT);
+    auto ret = ta.Connect();
+    if (!ret.ok()) {
+        android::trusty::fuzz::Abort();
+    }
+    int chan = *ta.GetRawFd();
+
+    alarm(kTimeoutSeconds);
+    bool success = Init(chan, dma_buf);
+    alarm(0);
+    if (!success) {
+        android::trusty::fuzz::Abort();
+    }
+
+    alarm(kTimeoutSeconds);
+    success = Msg(chan, data, size);
+    alarm(0);
+    if (!success) {
+        android::trusty::fuzz::Abort();
+    }
+
+    return 0;
+}
diff --git a/trusty/confirmationui/TrustyIpc.h b/trusty/confirmationui/include/TrustyIpc.h
similarity index 100%
rename from trusty/confirmationui/TrustyIpc.h
rename to trusty/confirmationui/include/TrustyIpc.h
diff --git a/trusty/coverage/Android.bp b/trusty/coverage/Android.bp
index c71d599..0453f3f 100644
--- a/trusty/coverage/Android.bp
+++ b/trusty/coverage/Android.bp
@@ -21,12 +21,14 @@
     vendor_available: true,
     srcs: [
         "coverage.cpp",
+        "uuid.cpp",
     ],
     export_include_dirs: [
         "include",
     ],
     shared_libs: [
         "libbase",
+        "libext2_uuid",
         "liblog",
         "libdmabufheap",
         "libtrusty",
diff --git a/trusty/coverage/include/trusty/coverage/tipc.h b/trusty/coverage/include/trusty/coverage/tipc.h
index c4157c4..386b2bb 100644
--- a/trusty/coverage/include/trusty/coverage/tipc.h
+++ b/trusty/coverage/include/trusty/coverage/tipc.h
@@ -19,16 +19,10 @@
 #pragma once
 
 #include <stdint.h>
+#include <trusty/coverage/uuid.h>
 
 #define COVERAGE_CLIENT_PORT "com.android.trusty.coverage.client"
 
-struct uuid {
-    uint32_t time_low;
-    uint16_t time_mid;
-    uint16_t time_hi_and_version;
-    uint8_t clock_seq_and_node[8];
-};
-
 enum coverage_client_cmd {
     COVERAGE_CLIENT_CMD_RESP_BIT = 1U,
     COVERAGE_CLIENT_CMD_SHIFT = 1U,
diff --git a/trusty/coverage/include/trusty/coverage/uuid.h b/trusty/coverage/include/trusty/coverage/uuid.h
new file mode 100644
index 0000000..c77d275
--- /dev/null
+++ b/trusty/coverage/include/trusty/coverage/uuid.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+struct uuid {
+    uint32_t time_low;
+    uint16_t time_mid;
+    uint16_t time_hi_and_version;
+    uint8_t clock_seq_and_node[8];
+};
+
+/**
+ * str_to_uuid() - Converts a C string into a uuid
+ * @str: C-string representation of the uuid
+ * @uuid: &struct uuid to fill with the converted uuid
+ *
+ * Return: true on success, false otherwise
+ */
+bool str_to_uuid(const char* str, struct uuid* uuid);
diff --git a/trusty/coverage/uuid.cpp b/trusty/coverage/uuid.cpp
new file mode 100644
index 0000000..f0a6c0e
--- /dev/null
+++ b/trusty/coverage/uuid.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 The Android Open Sourete 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 <string.h>
+#include <trusty/coverage/uuid.h>
+#include <uuid.h>
+
+#include <stdio.h>
+
+static uint16_t reverse_u16(uint16_t u) {
+    return u << 8 | u >> 8;
+}
+
+static uint32_t reverse_u32(uint32_t u) {
+    return reverse_u16((uint16_t)u) << 16 | reverse_u16(u >> 16);
+}
+
+bool str_to_uuid(const char* str, struct uuid* uuid) {
+    uuid_t uu;
+    static_assert(sizeof(uu) == sizeof(*uuid));
+
+    if (uuid_parse(str, uu)) {
+        return false;
+    }
+
+    memcpy(uuid, uu, sizeof(*uuid));
+    uuid->time_low = reverse_u32(uuid->time_low);
+    uuid->time_mid = reverse_u16(uuid->time_mid);
+    uuid->time_hi_and_version = reverse_u16(uuid->time_hi_and_version);
+    return true;
+}
diff --git a/trusty/fuzz/Android.bp b/trusty/fuzz/Android.bp
index 99156f4..d147767 100644
--- a/trusty/fuzz/Android.bp
+++ b/trusty/fuzz/Android.bp
@@ -52,3 +52,12 @@
         "libtrusty",
     ],
 }
+
+// Generic TIPC fuzzer, must parameterized using:
+//  -DTRUSTY_APP_PORT=<port name of TA being fuzzed>
+//  -DTRUSTY_APP_UUID=<UUID of TA being fuzzed>
+//  -DTRUSTY_APP_FILENAME=<name of symbolized elf binary of the TA>
+filegroup {
+    name: "trusty_tipc_fuzzer",
+    srcs: ["tipc_fuzzer.cpp"],
+}
diff --git a/trusty/fuzz/test/Android.bp b/trusty/fuzz/test/Android.bp
index 932121a..7d74913 100644
--- a/trusty/fuzz/test/Android.bp
+++ b/trusty/fuzz/test/Android.bp
@@ -19,5 +19,10 @@
 cc_fuzz {
     name: "trusty_test_fuzzer",
     defaults: ["trusty_fuzzer_defaults"],
-    srcs: ["fuzz.cpp"],
+    srcs: [":trusty_tipc_fuzzer"],
+    cflags: [
+        "-DTRUSTY_APP_PORT=\"com.android.trusty.sancov.test.srv\"",
+        "-DTRUSTY_APP_UUID=\"77f68803-c514-43ba-bdce-3254531c3d24\"",
+        "-DTRUSTY_APP_FILENAME=\"srv.syms.elf\"",
+    ]
 }
diff --git a/trusty/fuzz/test/fuzz.cpp b/trusty/fuzz/test/fuzz.cpp
deleted file mode 100644
index e7913db..0000000
--- a/trusty/fuzz/test/fuzz.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2020 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 <stdlib.h>
-#include <trusty/coverage/coverage.h>
-#include <trusty/fuzz/counters.h>
-#include <trusty/fuzz/utils.h>
-#include <unistd.h>
-#include <iostream>
-
-using android::trusty::coverage::CoverageRecord;
-using android::trusty::fuzz::ExtraCounters;
-using android::trusty::fuzz::TrustyApp;
-
-#define TIPC_DEV "/dev/trusty-ipc-dev0"
-#define TEST_SRV_PORT "com.android.trusty.sancov.test.srv"
-
-/* Test server's UUID is 77f68803-c514-43ba-bdce-3254531c3d24 */
-static struct uuid test_srv_uuid = {
-        0x77f68803,
-        0xc514,
-        0x43ba,
-        {0xbd, 0xce, 0x32, 0x54, 0x53, 0x1c, 0x3d, 0x24},
-};
-
-static CoverageRecord record(TIPC_DEV, &test_srv_uuid);
-
-extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
-    auto ret = record.Open();
-    if (!ret.ok()) {
-        std::cerr << ret.error() << std::endl;
-        exit(-1);
-    }
-    return 0;
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-    static uint8_t buf[TIPC_MAX_MSG_SIZE];
-
-    ExtraCounters counters(&record);
-    counters.Reset();
-
-    TrustyApp ta(TIPC_DEV, TEST_SRV_PORT);
-    auto ret = ta.Connect();
-    if (!ret.ok()) {
-        android::trusty::fuzz::Abort();
-    }
-
-    /* Send message to test server */
-    ret = ta.Write(data, size);
-    if (!ret.ok()) {
-        return -1;
-    }
-
-    /* Read message from test server */
-    ret = ta.Read(&buf, sizeof(buf));
-    if (!ret.ok()) {
-        return -1;
-    }
-
-    return 0;
-}
diff --git a/trusty/fuzz/tipc_fuzzer.cpp b/trusty/fuzz/tipc_fuzzer.cpp
new file mode 100644
index 0000000..24b0f98
--- /dev/null
+++ b/trusty/fuzz/tipc_fuzzer.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2021 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 <stdlib.h>
+#include <trusty/coverage/coverage.h>
+#include <trusty/coverage/uuid.h>
+#include <trusty/fuzz/counters.h>
+#include <trusty/fuzz/utils.h>
+#include <unistd.h>
+#include <iostream>
+#include <memory>
+
+using android::trusty::coverage::CoverageRecord;
+using android::trusty::fuzz::ExtraCounters;
+using android::trusty::fuzz::TrustyApp;
+
+#define TIPC_DEV "/dev/trusty-ipc-dev0"
+
+#ifndef TRUSTY_APP_PORT
+#error "Port name must be parameterized using -DTRUSTY_APP_PORT."
+#endif
+
+#ifndef TRUSTY_APP_UUID
+#error "UUID must be parameterized using -DTRUSTY_APP_UUID."
+#endif
+
+#ifndef TRUSTY_APP_FILENAME
+#error "Binary file name must be parameterized using -DTRUSTY_APP_FILENAME."
+#endif
+
+static std::unique_ptr<CoverageRecord> record;
+
+extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
+    uuid module_uuid;
+
+    if (!str_to_uuid(TRUSTY_APP_UUID, &module_uuid)) {
+        std::cerr << "Failed to parse UUID: " << TRUSTY_APP_UUID << std::endl;
+        exit(-1);
+    }
+
+    record = std::make_unique<CoverageRecord>(TIPC_DEV, &module_uuid, TRUSTY_APP_FILENAME);
+    if (!record) {
+        std::cerr << "Failed to allocate coverage record" << std::endl;
+        exit(-1);
+    }
+
+    auto ret = record->Open();
+    if (!ret.ok()) {
+        std::cerr << ret.error() << std::endl;
+        exit(-1);
+    }
+    return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    static uint8_t buf[TIPC_MAX_MSG_SIZE];
+
+    ExtraCounters counters(record.get());
+    counters.Reset();
+
+    TrustyApp ta(TIPC_DEV, TRUSTY_APP_PORT);
+    auto ret = ta.Connect();
+    if (!ret.ok()) {
+        std::cerr << ret.error() << std::endl;
+        android::trusty::fuzz::Abort();
+    }
+
+    ret = ta.Write(data, size);
+    if (!ret.ok()) {
+        return -1;
+    }
+
+    ret = ta.Read(&buf, sizeof(buf));
+    if (!ret.ok()) {
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/trusty/gatekeeper/fuzz/Android.bp b/trusty/gatekeeper/fuzz/Android.bp
index 6ff68b6..d084cb6 100644
--- a/trusty/gatekeeper/fuzz/Android.bp
+++ b/trusty/gatekeeper/fuzz/Android.bp
@@ -19,7 +19,12 @@
 cc_fuzz {
     name: "trusty_gatekeeper_fuzzer",
     defaults: ["trusty_fuzzer_defaults"],
-    srcs: ["fuzz.cpp"],
+    srcs: [":trusty_tipc_fuzzer"],
+    cflags: [
+        "-DTRUSTY_APP_PORT=\"com.android.trusty.gatekeeper\"",
+        "-DTRUSTY_APP_UUID=\"38ba0cdc-df0e-11e4-9869-233fb6ae4795\"",
+        "-DTRUSTY_APP_FILENAME=\"gatekeeper.syms.elf\"",
+    ],
 
     // The initial corpus for this fuzzer was derived by dumping messages from
     // the `secure_env` emulator interface for cuttlefish while enrolling a new
diff --git a/trusty/gatekeeper/fuzz/fuzz.cpp b/trusty/gatekeeper/fuzz/fuzz.cpp
deleted file mode 100644
index 7bfd7d1..0000000
--- a/trusty/gatekeeper/fuzz/fuzz.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2020 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 <stdlib.h>
-#include <trusty/coverage/coverage.h>
-#include <trusty/fuzz/counters.h>
-#include <trusty/fuzz/utils.h>
-#include <unistd.h>
-#include <iostream>
-
-using android::trusty::coverage::CoverageRecord;
-using android::trusty::fuzz::ExtraCounters;
-using android::trusty::fuzz::TrustyApp;
-
-#define TIPC_DEV "/dev/trusty-ipc-dev0"
-#define GATEKEEPER_PORT "com.android.trusty.gatekeeper"
-#define GATEKEEPER_MODULE_NAME "gatekeeper.syms.elf"
-
-/* Gatekeeper TA's UUID is 38ba0cdc-df0e-11e4-9869-233fb6ae4795 */
-static struct uuid gatekeeper_uuid = {
-        0x38ba0cdc,
-        0xdf0e,
-        0x11e4,
-        {0x98, 0x69, 0x23, 0x3f, 0xb6, 0xae, 0x47, 0x95},
-};
-
-static CoverageRecord record(TIPC_DEV, &gatekeeper_uuid, GATEKEEPER_MODULE_NAME);
-
-extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
-    auto ret = record.Open();
-    if (!ret.ok()) {
-        std::cerr << ret.error() << std::endl;
-        exit(-1);
-    }
-    return 0;
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-    static uint8_t buf[TIPC_MAX_MSG_SIZE];
-
-    ExtraCounters counters(&record);
-    counters.Reset();
-
-    android::trusty::fuzz::TrustyApp ta(TIPC_DEV, GATEKEEPER_PORT);
-    auto ret = ta.Connect();
-    if (!ret.ok()) {
-        android::trusty::fuzz::Abort();
-    }
-
-    /* Send message to test server */
-    ret = ta.Write(data, size);
-    if (!ret.ok()) {
-        return -1;
-    }
-
-    /* Read message from test server */
-    ret = ta.Read(&buf, sizeof(buf));
-    if (!ret.ok()) {
-        return -1;
-    }
-
-    return 0;
-}
diff --git a/trusty/keymaster/fuzz/Android.bp b/trusty/keymaster/fuzz/Android.bp
index 48c4e3a..8d7ee00 100644
--- a/trusty/keymaster/fuzz/Android.bp
+++ b/trusty/keymaster/fuzz/Android.bp
@@ -19,7 +19,12 @@
 cc_fuzz {
     name: "trusty_keymaster_fuzzer",
     defaults: ["trusty_fuzzer_defaults"],
-    srcs: ["fuzz.cpp"],
+    srcs: [":trusty_tipc_fuzzer"],
+    cflags: [
+        "-DTRUSTY_APP_PORT=\"com.android.trusty.keymaster\"",
+        "-DTRUSTY_APP_UUID=\"5f902ace-5e5c-4cd8-ae54-87b88c22ddaf\"",
+        "-DTRUSTY_APP_FILENAME=\"keymaster.syms.elf\"",
+    ],
 
     // The initial corpus for this fuzzer was derived by dumping messages from
     // the `secure_env` emulator interface for cuttlefish while running the
diff --git a/trusty/keymaster/fuzz/fuzz.cpp b/trusty/keymaster/fuzz/fuzz.cpp
deleted file mode 100644
index 4ac97bb..0000000
--- a/trusty/keymaster/fuzz/fuzz.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2020 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 <stdlib.h>
-#include <trusty/coverage/coverage.h>
-#include <trusty/fuzz/counters.h>
-#include <trusty/fuzz/utils.h>
-#include <unistd.h>
-#include <iostream>
-
-using android::trusty::coverage::CoverageRecord;
-using android::trusty::fuzz::ExtraCounters;
-using android::trusty::fuzz::TrustyApp;
-
-#define TIPC_DEV "/dev/trusty-ipc-dev0"
-#define KEYMASTER_PORT "com.android.trusty.keymaster"
-#define KEYMASTER_MODULE_FILENAME "keymaster.syms.elf"
-
-/* Keymaster TA's UUID is 5f902ace-5e5c-4cd8-ae54-87b88c22ddaf */
-static struct uuid keymaster_uuid = {
-        0x5f902ace,
-        0x5e5c,
-        0x4cd8,
-        {0xae, 0x54, 0x87, 0xb8, 0x8c, 0x22, 0xdd, 0xaf},
-};
-
-static CoverageRecord record(TIPC_DEV, &keymaster_uuid, KEYMASTER_MODULE_FILENAME);
-
-extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
-    auto ret = record.Open();
-    if (!ret.ok()) {
-        std::cerr << ret.error() << std::endl;
-        exit(-1);
-    }
-    return 0;
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-    static uint8_t buf[TIPC_MAX_MSG_SIZE];
-
-    ExtraCounters counters(&record);
-    counters.Reset();
-
-    android::trusty::fuzz::TrustyApp ta(TIPC_DEV, KEYMASTER_PORT);
-    auto ret = ta.Connect();
-    if (!ret.ok()) {
-        android::trusty::fuzz::Abort();
-    }
-
-    /* Send message to test server */
-    ret = ta.Write(data, size);
-    if (!ret.ok()) {
-        return -1;
-    }
-
-    /* Read message from test server */
-    ret = ta.Read(&buf, sizeof(buf));
-    if (!ret.ok()) {
-        return -1;
-    }
-
-    return 0;
-}