Merge "raise debuggerd_test timeout" into main
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 235d723..12a1ddc 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -571,7 +571,8 @@
             "                            Format a flash partition.\n"
             " set_active SLOT            Set the active slot.\n"
             " oem [COMMAND...]           Execute OEM-specific command.\n"
-            " gsi wipe|disable           Wipe or disable a GSI installation (fastbootd only).\n"
+            " gsi wipe|disable|status    Wipe, disable or show status of a GSI installation\n"
+            "                            (fastbootd only).\n"
             " wipe-super [SUPER_EMPTY]   Wipe the super partition. This will reset it to\n"
             "                            contain an empty set of default dynamic partitions.\n"
             " create-logical-partition NAME SIZE\n"
diff --git a/fs_mgr/libfs_avb/fs_avb.cpp b/fs_mgr/libfs_avb/fs_avb.cpp
index fb22423..be48de6 100644
--- a/fs_mgr/libfs_avb/fs_avb.cpp
+++ b/fs_mgr/libfs_avb/fs_avb.cpp
@@ -288,14 +288,82 @@
     return false;
 }
 
-AvbUniquePtr AvbHandle::LoadAndVerifyVbmeta(const FstabEntry& fstab_entry,
-                                            const std::vector<std::string>& preload_avb_key_blobs) {
+bool IsPublicKeyMatching(const FstabEntry& fstab_entry, const std::string& public_key_data,
+                         const std::vector<std::string>& preload_avb_key_blobs) {
     // At least one of the following should be provided for public key matching.
     if (preload_avb_key_blobs.empty() && fstab_entry.avb_keys.empty()) {
         LERROR << "avb_keys=/path/to/key(s) is missing for " << fstab_entry.mount_point;
-        return nullptr;
+        return false;
     }
 
+    // Expected key shouldn't be empty.
+    if (public_key_data.empty()) {
+        LERROR << "public key data shouldn't be empty for " << fstab_entry.mount_point;
+        return false;
+    }
+
+    // Performs key matching for preload_avb_key_blobs first, if it is present.
+    if (!preload_avb_key_blobs.empty()) {
+        if (std::find(preload_avb_key_blobs.begin(), preload_avb_key_blobs.end(),
+                      public_key_data) != preload_avb_key_blobs.end()) {
+            return true;
+        }
+    }
+
+    // Performs key matching for fstab_entry.avb_keys if necessary.
+    // Note that it is intentional to match both preload_avb_key_blobs and fstab_entry.avb_keys.
+    // Some keys might only be available before init chroots into /system, e.g., /avb/key1
+    // in the first-stage ramdisk, while other keys might only be available after the chroot,
+    // e.g., /system/etc/avb/key2.
+    // fstab_entry.avb_keys might be either a directory containing multiple keys,
+    // or a string indicating multiple keys separated by ':'.
+    std::vector<std::string> allowed_avb_keys;
+    auto list_avb_keys_in_dir = ListFiles(fstab_entry.avb_keys);
+    if (list_avb_keys_in_dir.ok()) {
+        std::sort(list_avb_keys_in_dir->begin(), list_avb_keys_in_dir->end());
+        allowed_avb_keys = *list_avb_keys_in_dir;
+    } else {
+        allowed_avb_keys = Split(fstab_entry.avb_keys, ":");
+    }
+    return ValidatePublicKeyBlob(public_key_data, allowed_avb_keys);
+}
+
+bool IsHashtreeDescriptorRootDigestMatching(const FstabEntry& fstab_entry,
+                                            const std::vector<VBMetaData>& vbmeta_images,
+                                            const std::string& ab_suffix,
+                                            const std::string& ab_other_suffix) {
+    // Read expected value of hashtree descriptor root digest from fstab_entry.
+    std::string root_digest_expected;
+    if (!ReadFileToString(fstab_entry.avb_hashtree_digest, &root_digest_expected)) {
+        LERROR << "Failed to load expected root digest for " << fstab_entry.mount_point;
+        return false;
+    }
+
+    // Read actual hashtree descriptor from vbmeta image.
+    std::string partition_name = DeriveAvbPartitionName(fstab_entry, ab_suffix, ab_other_suffix);
+    if (partition_name.empty()) {
+        LERROR << "Failed to find partition name for " << fstab_entry.mount_point;
+        return false;
+    }
+    std::unique_ptr<FsAvbHashtreeDescriptor> hashtree_descriptor =
+            android::fs_mgr::GetHashtreeDescriptor(partition_name, vbmeta_images);
+    if (!hashtree_descriptor) {
+        LERROR << "Not found hashtree descriptor for " << fstab_entry.mount_point;
+        return false;
+    }
+
+    // Performs hashtree descriptor root digest matching.
+    if (hashtree_descriptor->root_digest != root_digest_expected) {
+        LERROR << "root digest (" << hashtree_descriptor->root_digest
+               << ") is different from expected value (" << root_digest_expected << ")";
+        return false;
+    }
+
+    return true;
+}
+
+AvbUniquePtr AvbHandle::LoadAndVerifyVbmeta(const FstabEntry& fstab_entry,
+                                            const std::vector<std::string>& preload_avb_key_blobs) {
     // Binds allow_verification_error and rollback_protection to device unlock state.
     bool allow_verification_error = IsAvbPermissive();
     bool rollback_protection = !allow_verification_error;
@@ -333,40 +401,24 @@
             return nullptr;
     }
 
-    bool public_key_match = false;
-    // Performs key matching for preload_avb_key_blobs first, if it is present.
-    if (!public_key_data.empty() && !preload_avb_key_blobs.empty()) {
-        if (std::find(preload_avb_key_blobs.begin(), preload_avb_key_blobs.end(),
-                      public_key_data) != preload_avb_key_blobs.end()) {
-            public_key_match = true;
+    // Verify vbmeta image checking by either public key or hashtree descriptor root digest.
+    if (!preload_avb_key_blobs.empty() || !fstab_entry.avb_keys.empty()) {
+        if (!IsPublicKeyMatching(fstab_entry, public_key_data, preload_avb_key_blobs)) {
+            avb_handle->status_ = AvbHandleStatus::kVerificationError;
+            LWARNING << "Found unknown public key used to sign " << fstab_entry.mount_point;
+            if (!allow_verification_error) {
+                LERROR << "Unknown public key is not allowed";
+                return nullptr;
+            }
         }
-    }
-    // Performs key matching for fstab_entry.avb_keys if necessary.
-    // Note that it is intentional to match both preload_avb_key_blobs and fstab_entry.avb_keys.
-    // Some keys might only be availble before init chroots into /system, e.g., /avb/key1
-    // in the first-stage ramdisk, while other keys might only be available after the chroot,
-    // e.g., /system/etc/avb/key2.
-    if (!public_key_data.empty() && !public_key_match) {
-        // fstab_entry.avb_keys might be either a directory containing multiple keys,
-        // or a string indicating multiple keys separated by ':'.
-        std::vector<std::string> allowed_avb_keys;
-        auto list_avb_keys_in_dir = ListFiles(fstab_entry.avb_keys);
-        if (list_avb_keys_in_dir.ok()) {
-            std::sort(list_avb_keys_in_dir->begin(), list_avb_keys_in_dir->end());
-            allowed_avb_keys = *list_avb_keys_in_dir;
-        } else {
-            allowed_avb_keys = Split(fstab_entry.avb_keys, ":");
-        }
-        if (ValidatePublicKeyBlob(public_key_data, allowed_avb_keys)) {
-            public_key_match = true;
-        }
-    }
-
-    if (!public_key_match) {
+    } else if (!IsHashtreeDescriptorRootDigestMatching(fstab_entry, avb_handle->vbmeta_images_,
+                                                       avb_handle->slot_suffix_,
+                                                       avb_handle->other_slot_suffix_)) {
         avb_handle->status_ = AvbHandleStatus::kVerificationError;
-        LWARNING << "Found unknown public key used to sign " << fstab_entry.mount_point;
+        LWARNING << "Found unknown hashtree descriptor root digest used on "
+                 << fstab_entry.mount_point;
         if (!allow_verification_error) {
-            LERROR << "Unknown public key is not allowed";
+            LERROR << "Verification based on root digest failed. Vbmeta image is not allowed.";
             return nullptr;
         }
     }
diff --git a/fs_mgr/libfstab/fstab.cpp b/fs_mgr/libfstab/fstab.cpp
index 443017a..6fa22fe 100644
--- a/fs_mgr/libfstab/fstab.cpp
+++ b/fs_mgr/libfstab/fstab.cpp
@@ -286,6 +286,10 @@
             }
         } else if (StartsWith(flag, "avb_keys=")) {  // must before the following "avb"
             entry->avb_keys = arg;
+        } else if (StartsWith(flag, "avb_hashtree_digest=")) {
+            // "avb_hashtree_digest" must before the following "avb"
+            // The path where hex-encoded hashtree descriptor root digest is located.
+            entry->avb_hashtree_digest = arg;
         } else if (StartsWith(flag, "avb")) {
             entry->fs_mgr_flags.avb = true;
             entry->vbmeta_partition = arg;
diff --git a/fs_mgr/libfstab/include/fstab/fstab.h b/fs_mgr/libfstab/include/fstab/fstab.h
index 09471f0..5e4019c 100644
--- a/fs_mgr/libfstab/include/fstab/fstab.h
+++ b/fs_mgr/libfstab/include/fstab/fstab.h
@@ -57,6 +57,7 @@
     uint64_t zram_backingdev_size = 0;
     std::string avb_keys;
     std::string lowerdir;
+    std::string avb_hashtree_digest;
 
     struct FsMgrFlags {
         bool wait : 1;
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index d0f68a8..c0b9281 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -732,6 +732,15 @@
     return true;
 }
 
+bool IsHashtreeDisabled(const AvbHandle& vbmeta, const std::string& mount_point) {
+    if (vbmeta.status() == AvbHandleStatus::kHashtreeDisabled ||
+        vbmeta.status() == AvbHandleStatus::kVerificationDisabled) {
+        LOG(ERROR) << "Top-level vbmeta is disabled, skip Hashtree setup for " << mount_point;
+        return true;  // Returns true to mount the partition directly.
+    }
+    return false;
+}
+
 bool FirstStageMountVBootV2::SetUpDmVerity(FstabEntry* fstab_entry) {
     AvbHashtreeResult hashtree_result;
 
@@ -740,34 +749,46 @@
     if (!fstab_entry->avb_keys.empty()) {
         if (!InitAvbHandle()) return false;
         // Checks if hashtree should be disabled from the top-level /vbmeta.
-        if (avb_handle_->status() == AvbHandleStatus::kHashtreeDisabled ||
-            avb_handle_->status() == AvbHandleStatus::kVerificationDisabled) {
-            LOG(ERROR) << "Top-level vbmeta is disabled, skip Hashtree setup for "
-                       << fstab_entry->mount_point;
-            return true;  // Returns true to mount the partition directly.
+        if (IsHashtreeDisabled(*avb_handle_, fstab_entry->mount_point)) {
+            return true;
+        }
+        auto avb_standalone_handle = AvbHandle::LoadAndVerifyVbmeta(
+                *fstab_entry, preload_avb_key_blobs_[fstab_entry->avb_keys]);
+        if (!avb_standalone_handle) {
+            LOG(ERROR) << "Failed to load offline vbmeta for " << fstab_entry->mount_point;
+            // Fallbacks to built-in hashtree if fs_mgr_flags.avb is set.
+            if (!fstab_entry->fs_mgr_flags.avb) return false;
+            LOG(INFO) << "Fallback to built-in hashtree for " << fstab_entry->mount_point;
+            hashtree_result =
+                    avb_handle_->SetUpAvbHashtree(fstab_entry, false /* wait_for_verity_dev */);
         } else {
-            auto avb_standalone_handle = AvbHandle::LoadAndVerifyVbmeta(
-                    *fstab_entry, preload_avb_key_blobs_[fstab_entry->avb_keys]);
-            if (!avb_standalone_handle) {
-                LOG(ERROR) << "Failed to load offline vbmeta for " << fstab_entry->mount_point;
-                // Fallbacks to built-in hashtree if fs_mgr_flags.avb is set.
-                if (!fstab_entry->fs_mgr_flags.avb) return false;
-                LOG(INFO) << "Fallback to built-in hashtree for " << fstab_entry->mount_point;
-                hashtree_result =
-                        avb_handle_->SetUpAvbHashtree(fstab_entry, false /* wait_for_verity_dev */);
-            } else {
-                // Sets up hashtree via the standalone handle.
-                if (IsStandaloneImageRollback(*avb_handle_, *avb_standalone_handle, *fstab_entry)) {
-                    return false;
-                }
-                hashtree_result = avb_standalone_handle->SetUpAvbHashtree(
-                        fstab_entry, false /* wait_for_verity_dev */);
+            // Sets up hashtree via the standalone handle.
+            if (IsStandaloneImageRollback(*avb_handle_, *avb_standalone_handle, *fstab_entry)) {
+                return false;
             }
+            hashtree_result = avb_standalone_handle->SetUpAvbHashtree(
+                    fstab_entry, false /* wait_for_verity_dev */);
         }
     } else if (fstab_entry->fs_mgr_flags.avb) {
         if (!InitAvbHandle()) return false;
         hashtree_result =
                 avb_handle_->SetUpAvbHashtree(fstab_entry, false /* wait_for_verity_dev */);
+    } else if (!fstab_entry->avb_hashtree_digest.empty()) {
+        // When fstab_entry has neither avb_keys nor avb flag, try using
+        // avb_hashtree_digest.
+        if (!InitAvbHandle()) return false;
+        // Checks if hashtree should be disabled from the top-level /vbmeta.
+        if (IsHashtreeDisabled(*avb_handle_, fstab_entry->mount_point)) {
+            return true;
+        }
+        auto avb_standalone_handle = AvbHandle::LoadAndVerifyVbmeta(*fstab_entry);
+        if (!avb_standalone_handle) {
+            LOG(ERROR) << "Failed to load vbmeta based on hashtree descriptor root digest for "
+                       << fstab_entry->mount_point;
+            return false;
+        }
+        hashtree_result = avb_standalone_handle->SetUpAvbHashtree(fstab_entry,
+                                                                  false /* wait_for_verity_dev */);
     } else {
         return true;  // No need AVB, returns true to mount the partition directly.
     }
diff --git a/janitors/OWNERS b/janitors/OWNERS
index d871201..a28737e 100644
--- a/janitors/OWNERS
+++ b/janitors/OWNERS
@@ -3,5 +3,4 @@
 cferris@google.com
 dwillemsen@google.com
 enh@google.com
-narayan@google.com
 sadafebrahimi@google.com
diff --git a/libvndksupport/include/vndksupport/linker.h b/libvndksupport/include/vndksupport/linker.h
index 5f48c39..6845135 100644
--- a/libvndksupport/include/vndksupport/linker.h
+++ b/libvndksupport/include/vndksupport/linker.h
@@ -20,15 +20,8 @@
 extern "C" {
 #endif
 
-/*
- * Returns whether the current process is a vendor process.
- *
- * Note that this is only checking what process is running and has nothing to
- * do with what namespace the caller is loaded at.  For example, a VNDK-SP
- * library loaded by SP-HAL calling this function may still get a 'false',
- * because it is running in a system process.
- */
-int android_is_in_vendor_process();
+int android_is_in_vendor_process() __attribute__((
+        deprecated("This function would not give exact result if VNDK is deprecated.")));
 
 void* android_load_sphal_library(const char* name, int flag);
 
diff --git a/libvndksupport/libvndksupport.map.txt b/libvndksupport/libvndksupport.map.txt
index 1d94b9d..325505d 100644
--- a/libvndksupport/libvndksupport.map.txt
+++ b/libvndksupport/libvndksupport.map.txt
@@ -1,6 +1,6 @@
 LIBVNDKSUPPORT {
   global:
-    android_is_in_vendor_process; # llndk systemapi
+    android_is_in_vendor_process; # llndk-deprecated=35 systemapi
     android_load_sphal_library; # llndk systemapi
     android_unload_sphal_library; # llndk systemapi
   local: