Merge "pvmfw: parse and validate incoming device tree"
diff --git a/compos/composd/src/instance_manager.rs b/compos/composd/src/instance_manager.rs
index 2db13c7..98d4a1b 100644
--- a/compos/composd/src/instance_manager.rs
+++ b/compos/composd/src/instance_manager.rs
@@ -27,7 +27,7 @@
 use virtualizationservice::IVirtualizationService::IVirtualizationService;
 
 // Enough memory to complete odrefresh in the VM.
-const VM_MEMORY_MIB: i32 = 1280;
+const VM_MEMORY_MIB: i32 = 1024;
 
 pub struct InstanceManager {
     service: Strong<dyn IVirtualizationService>,
diff --git a/docs/debug/tracing.md b/docs/debug/tracing.md
index 7d7ea0c..0038440 100644
--- a/docs/debug/tracing.md
+++ b/docs/debug/tracing.md
@@ -72,4 +72,49 @@
 
 ## Microdroid VM tracing
 
+IMPORTANT: Tracing is only supported for debuggable Microdroid VMs.
+
+### Capturing trace in Microdroid
+
+Starting with Android U, Microdroid contains Perfetto tracing binaries, which makes it possible to
+capture traces inside Microdroid VM using Perfetto stack. The commands used to capture traces on
+Android should work for Microdroid VM as well, with a difference that Perfetto's tracing binaries
+are not enabled in Microdroid by default, so you need to manually start them by setting
+`persist.traced.enable` system property to `1`.
+
+Here is a quick example on how trace Microdroid VM:
+
+1. First start your VM. For this example we are going to use
+`adb shell /apex/com.android.virt/bin/vm run-microdroid`.
+
+2. Set up an adb connection with the running VM:
+```shell
+adb shell forward tcp:9876 vsock:${CID}:5555
+adb connect localhost:9876
+adb -s localhost:9876 root
+```
+Where `${CID}` corresponds to the running Microdroid VM that you want to establish adb connection
+with. List of running VMs can be obtained by running `adb shell /apex/com.android.virt/bin/vm list`.
+Alternatively you can use `vm_shell` utility to connect to a running VM, i.e.: `vm_shell connect`.
+
+3. Start Perfetto daemons and capture trace
+```shell
+adb -s localhost:9876 shell setprop persist.traced.enable 1
+${ANDROID_BULD_TOP}/external/perfetto/tools/record_android_trace \
+  -s localhost:9876 \
+  -o /tmp/microdroid-trace-file.pftrace \
+  -t 10s \
+  -b 32mb \
+  sched/sched_switch task/task_newtask sched/sched_process_exit
+```
+
+If you don't have Android repo checked out, then you can download the record_android_trace script by
+following the following [instructions](
+https://perfetto.dev/docs/quickstart/android-tracing#recording-a-trace-through-the-cmdline)
+
+More documentation on Perfetto's tracing on Android is available here:
+https://perfetto.dev/docs/quickstart/android-tracing
+
+### Capturing Microdroid boot trace
+
 TODO(b/271412868): Stay tuned, more docs are coming soon!
diff --git a/libs/apkverify/Android.bp b/libs/apkverify/Android.bp
index e556842..83dbff6 100644
--- a/libs/apkverify/Android.bp
+++ b/libs/apkverify/Android.bp
@@ -45,7 +45,9 @@
     edition: "2021",
     test_suites: ["general-tests"],
     rustlibs: [
+        "libandroid_logger",
         "libapkverify",
+        "liblog_rust",
         "libzip",
     ],
     data: ["tests/data/*"],
diff --git a/libs/apkverify/tests/apkverify_test.rs b/libs/apkverify/tests/apkverify_test.rs
index f08b357..52e1da4 100644
--- a/libs/apkverify/tests/apkverify_test.rs
+++ b/libs/apkverify/tests/apkverify_test.rs
@@ -17,6 +17,7 @@
 use apkverify::{
     get_apk_digest, get_public_key_der, testing::assert_contains, verify, SignatureAlgorithmID,
 };
+use log::info;
 use std::{fs, matches, path::Path};
 
 const KEY_NAMES_DSA: &[&str] = &["1024", "2048", "3072"];
@@ -25,8 +26,19 @@
 
 const SDK_INT: u32 = 31;
 
+/// Make sure any logging from the code under test ends up in logcat.
+fn setup() {
+    android_logger::init_once(
+        android_logger::Config::default()
+            .with_tag("apkverify_test")
+            .with_min_level(log::Level::Info),
+    );
+    info!("Test starting");
+}
+
 #[test]
 fn test_verify_truncated_cd() {
+    setup();
     use zip::result::ZipError;
     let res = verify("tests/data/v2-only-truncated-cd.apk", SDK_INT);
     // TODO(b/190343842): consider making a helper for err assertion
@@ -38,11 +50,13 @@
 
 #[test]
 fn apex_signed_with_v3_rsa_pkcs1_sha512_is_valid() {
+    setup();
     validate_apk("tests/data/test.apex", SignatureAlgorithmID::RsaPkcs1V15WithSha512);
 }
 
 #[test]
 fn apks_signed_with_v3_dsa_sha256_are_not_supported() {
+    setup();
     for key_name in KEY_NAMES_DSA.iter() {
         let res = verify(format!("tests/data/v3-only-with-dsa-sha256-{}.apk", key_name), SDK_INT);
         assert!(res.is_err(), "DSA algorithm is not supported for verification. See b/197052981.");
@@ -52,6 +66,7 @@
 
 #[test]
 fn apks_signed_with_v3_ecdsa_sha256_are_valid() {
+    setup();
     for key_name in KEY_NAMES_ECDSA.iter() {
         validate_apk(
             format!("tests/data/v3-only-with-ecdsa-sha256-{}.apk", key_name),
@@ -62,6 +77,7 @@
 
 #[test]
 fn apks_signed_with_v3_ecdsa_sha512_are_valid() {
+    setup();
     for key_name in KEY_NAMES_ECDSA.iter() {
         validate_apk(
             format!("tests/data/v3-only-with-ecdsa-sha512-{}.apk", key_name),
@@ -72,6 +88,7 @@
 
 #[test]
 fn apks_signed_with_v3_rsa_pkcs1_sha256_are_valid() {
+    setup();
     for key_name in KEY_NAMES_RSA.iter() {
         validate_apk(
             format!("tests/data/v3-only-with-rsa-pkcs1-sha256-{}.apk", key_name),
@@ -82,6 +99,7 @@
 
 #[test]
 fn apks_signed_with_v3_rsa_pkcs1_sha512_are_valid() {
+    setup();
     for key_name in KEY_NAMES_RSA.iter() {
         validate_apk(
             format!("tests/data/v3-only-with-rsa-pkcs1-sha512-{}.apk", key_name),
@@ -91,7 +109,29 @@
 }
 
 #[test]
+fn test_verify_v3_sig_min_max_sdk() {
+    setup();
+    // The Signer for this APK has min_sdk=24, max_sdk=32.
+    let path = "tests/data/v31-rsa-2048_2-tgt-33-1-tgt-28.apk";
+
+    let res = verify(path, 23);
+    assert!(res.is_err());
+    assert_contains(&res.unwrap_err().to_string(), "0 signers found");
+
+    let res = verify(path, 24);
+    assert!(res.is_ok());
+
+    let res = verify(path, 32);
+    assert!(res.is_ok());
+
+    let res = verify(path, 33);
+    assert!(res.is_err());
+    assert_contains(&res.unwrap_err().to_string(), "0 signers found");
+}
+
+#[test]
 fn test_verify_v3_sig_does_not_verify() {
+    setup();
     let path_list = [
         "tests/data/v3-only-with-ecdsa-sha512-p521-sig-does-not-verify.apk",
         "tests/data/v3-only-with-rsa-pkcs1-sha256-3072-sig-does-not-verify.apk",
@@ -105,6 +145,7 @@
 
 #[test]
 fn test_verify_v3_digest_mismatch() {
+    setup();
     let res = verify("tests/data/v3-only-with-rsa-pkcs1-sha512-8192-digest-mismatch.apk", SDK_INT);
     assert!(res.is_err());
     assert_contains(&res.unwrap_err().to_string(), "Digest mismatch");
@@ -112,6 +153,7 @@
 
 #[test]
 fn test_verify_v3_wrong_apk_sig_block_magic() {
+    setup();
     let res =
         verify("tests/data/v3-only-with-ecdsa-sha512-p384-wrong-apk-sig-block-magic.apk", SDK_INT);
     assert!(res.is_err());
@@ -120,6 +162,7 @@
 
 #[test]
 fn test_verify_v3_apk_sig_block_size_mismatch() {
+    setup();
     let res = verify(
         "tests/data/v3-only-with-rsa-pkcs1-sha512-4096-apk-sig-block-size-mismatch.apk",
         SDK_INT,
@@ -133,6 +176,7 @@
 
 #[test]
 fn test_verify_v3_cert_and_public_key_mismatch() {
+    setup();
     let res = verify("tests/data/v3-only-cert-and-public-key-mismatch.apk", SDK_INT);
     assert!(res.is_err());
     assert_contains(&res.unwrap_err().to_string(), "Public key mismatch");
@@ -140,6 +184,7 @@
 
 #[test]
 fn test_verify_v3_empty() {
+    setup();
     let res = verify("tests/data/v3-only-empty.apk", SDK_INT);
     assert!(res.is_err());
     assert_contains(&res.unwrap_err().to_string(), "APK too small for APK Signing Block");
@@ -147,6 +192,7 @@
 
 #[test]
 fn test_verify_v3_no_certs_in_sig() {
+    setup();
     let res = verify("tests/data/v3-only-no-certs-in-sig.apk", SDK_INT);
     assert!(res.is_err());
     assert_contains(&res.unwrap_err().to_string(), "No certificates listed");
@@ -154,6 +200,7 @@
 
 #[test]
 fn test_verify_v3_no_supported_sig_algs() {
+    setup();
     let res = verify("tests/data/v3-only-no-supported-sig-algs.apk", SDK_INT);
     assert!(res.is_err());
     assert_contains(&res.unwrap_err().to_string(), "No supported APK signatures found");
@@ -161,6 +208,7 @@
 
 #[test]
 fn test_verify_v3_signatures_and_digests_block_mismatch() {
+    setup();
     let res = verify("tests/data/v3-only-signatures-and-digests-block-mismatch.apk", SDK_INT);
     assert!(res.is_err());
     assert_contains(
@@ -171,6 +219,7 @@
 
 #[test]
 fn apk_signed_with_v3_unknown_additional_attr_is_valid() {
+    setup();
     validate_apk(
         "tests/data/v3-only-unknown-additional-attr.apk",
         SignatureAlgorithmID::RsaPkcs1V15WithSha256,
@@ -179,6 +228,7 @@
 
 #[test]
 fn apk_signed_with_v3_unknown_pair_in_apk_sig_block_is_valid() {
+    setup();
     validate_apk(
         "tests/data/v3-only-unknown-pair-in-apk-sig-block.apk",
         SignatureAlgorithmID::RsaPkcs1V15WithSha256,
@@ -187,6 +237,7 @@
 
 #[test]
 fn apk_signed_with_v3_ignorable_unsupported_sig_algs_is_valid() {
+    setup();
     validate_apk(
         "tests/data/v3-only-with-ignorable-unsupported-sig-algs.apk",
         SignatureAlgorithmID::RsaPkcs1V15WithSha256,
@@ -195,6 +246,7 @@
 
 #[test]
 fn apk_signed_with_v3_stamp_is_valid() {
+    setup();
     validate_apk("tests/data/v3-only-with-stamp.apk", SignatureAlgorithmID::EcdsaWithSha256);
 }
 
diff --git a/libs/apkverify/tests/data/v31-rsa-2048_2-tgt-33-1-tgt-28.apk b/libs/apkverify/tests/data/v31-rsa-2048_2-tgt-33-1-tgt-28.apk
new file mode 100644
index 0000000..aeaec33
--- /dev/null
+++ b/libs/apkverify/tests/data/v31-rsa-2048_2-tgt-33-1-tgt-28.apk
Binary files differ
diff --git a/microdroid/Android.bp b/microdroid/Android.bp
index a2a4138..0abaf79 100644
--- a/microdroid/Android.bp
+++ b/microdroid/Android.bp
@@ -70,7 +70,6 @@
         "libartpalette-system",
 
         "apexd.microdroid",
-        "atrace",
         "debuggerd",
         "linker",
         "tombstoned.microdroid",
@@ -89,6 +88,12 @@
         "libvm_payload", // used by payload to interact with microdroid manager
 
         "prng_seeder_microdroid",
+
+        // Binaries required to capture traces in Microdroid.
+        "atrace",
+        "traced",
+        "traced_probes",
+        "perfetto",
     ] + microdroid_shell_and_utilities,
     multilib: {
         common: {
diff --git a/pvmfw/Android.bp b/pvmfw/Android.bp
index b56df4f..0d845f9 100644
--- a/pvmfw/Android.bp
+++ b/pvmfw/Android.bp
@@ -54,6 +54,7 @@
     // partition image. This is just to package the unstripped file into the
     // symbols zip file for debugging purpose.
     installable: true,
+    native_coverage: false,
 }
 
 raw_binary {
diff --git a/pvmfw/platform.dts b/pvmfw/platform.dts
index 056fa2f..127f69a 100644
--- a/pvmfw/platform.dts
+++ b/pvmfw/platform.dts
@@ -245,4 +245,11 @@
 		clock-names = "apb_pclk";
 		clocks = <&clk>;
 	};
+
+	vmwdt@3000 {
+		compatible = "qemu,vcpu-stall-detector";
+		reg = <0x00 0x3000 0x00 0x1000>;
+		clock-frequency = <10>;
+		timeout-sec = <8>;
+	};
 };