Merge "TerminalApp: Use sparse file for debian rootfs if storage balloon enabled" into main
diff --git a/android/TerminalApp/Android.bp b/android/TerminalApp/Android.bp
index e1e236a..c18ada4 100644
--- a/android/TerminalApp/Android.bp
+++ b/android/TerminalApp/Android.bp
@@ -14,6 +14,7 @@
// TODO(b/330257000): will be removed when binder RPC is used
"android.system.virtualizationservice_internal-java",
"androidx-constraintlayout_constraintlayout",
+ "androidx.navigation_navigation-fragment-ktx",
"androidx.window_window",
"androidx.work_work-runtime",
"apache-commons-compress",
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/InstalledImage.kt b/android/TerminalApp/java/com/android/virtualization/terminal/InstalledImage.kt
index 23bf48d..086ff3d 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/InstalledImage.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/InstalledImage.kt
@@ -120,11 +120,12 @@
val roundedUpDesiredSize = roundUp(desiredSize)
val curSize = getSize()
+ runE2fsck(rootPartition)
+
if (roundedUpDesiredSize == curSize) {
return roundedUpDesiredSize
}
- runE2fsck(rootPartition)
if (roundedUpDesiredSize > curSize) {
allocateSpace(rootPartition, roundedUpDesiredSize)
}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/Logger.kt b/android/TerminalApp/java/com/android/virtualization/terminal/Logger.kt
index 4162247..ba03716 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/Logger.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/Logger.kt
@@ -47,6 +47,10 @@
}
try {
+ if (Files.isRegularFile(dir)) {
+ Log.i(tag, "Removed legacy log file: $dir")
+ Files.delete(dir)
+ }
Files.createDirectories(dir)
deleteOldLogs(dir, 10)
val logPath = dir.resolve(LocalDateTime.now().toString() + ".txt")
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.kt b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.kt
index f4306bf..d85242b 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.kt
@@ -45,7 +45,7 @@
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
-import androidx.lifecycle.ViewModelProvider
+import androidx.activity.viewModels
import androidx.viewpager2.widget.ViewPager2
import com.android.internal.annotations.VisibleForTesting
import com.android.microdroid.test.common.DeviceProperties
@@ -72,11 +72,11 @@
private lateinit var image: InstalledImage
private lateinit var accessibilityManager: AccessibilityManager
private lateinit var manageExternalStorageActivityResultLauncher: ActivityResultLauncher<Intent>
- private lateinit var terminalViewModel: TerminalViewModel
private lateinit var viewPager: ViewPager2
private lateinit var tabLayout: TabLayout
private lateinit var terminalTabAdapter: TerminalTabAdapter
private val terminalInfo = CompletableFuture<TerminalInfo>()
+ private val terminalViewModel: TerminalViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -111,7 +111,6 @@
}
private fun initializeUi() {
- terminalViewModel = ViewModelProvider(this)[TerminalViewModel::class.java]
setContentView(R.layout.activity_headless)
tabLayout = findViewById<TabLayout>(R.id.tab_layout)
displayMenu = findViewById<Button>(R.id.display_button)
@@ -151,6 +150,20 @@
TabLayoutMediator(tabLayout, viewPager, false, false) { _: TabLayout.Tab?, _: Int -> }
.attach()
+ tabLayout.addOnTabSelectedListener(
+ object : TabLayout.OnTabSelectedListener {
+ override fun onTabSelected(tab: TabLayout.Tab?) {
+ tab?.position?.let {
+ terminalViewModel.selectedTabViewId = terminalTabAdapter.tabs[it].id
+ }
+ }
+
+ override fun onTabUnselected(tab: TabLayout.Tab?) {}
+
+ override fun onTabReselected(tab: TabLayout.Tab?) {}
+ }
+ )
+
addTerminalTab()
tabAddButton?.setOnClickListener { addTerminalTab() }
@@ -160,7 +173,9 @@
val tab = tabLayout.newTab()
tab.setCustomView(R.layout.tabitem_terminal)
viewPager.offscreenPageLimit += 1
- terminalTabAdapter.addTab()
+ val tabId = terminalTabAdapter.addTab()
+ terminalViewModel.selectedTabViewId = tabId
+ terminalViewModel.terminalTabs[tabId] = tab
tab.customView!!
.findViewById<Button>(R.id.tab_close_button)
.setOnClickListener(
@@ -223,9 +238,7 @@
"&fontWeightBold=" +
(FontStyle.FONT_WEIGHT_BOLD + config.fontWeightAdjustment) +
"&screenReaderMode=" +
- accessibilityManager.isEnabled +
- "&titleFixed=" +
- getString(R.string.app_name))
+ accessibilityManager.isEnabled)
try {
return URL("https", ipAddress, port, "/$query")
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalTabFragment.kt b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalTabFragment.kt
index 7e78235..a0c6e4e 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalTabFragment.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalTabFragment.kt
@@ -31,8 +31,9 @@
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
+import android.widget.TextView
import androidx.fragment.app.Fragment
-import androidx.lifecycle.ViewModelProvider
+import androidx.fragment.app.activityViewModels
import com.android.system.virtualmachine.flags.Flags.terminalGuiSupport
import com.android.virtualization.terminal.CertificateUtils.createOrGetKey
import com.android.virtualization.terminal.CertificateUtils.writeCertificateToFile
@@ -45,7 +46,7 @@
private lateinit var id: String
private var certificates: Array<X509Certificate>? = null
private var privateKey: PrivateKey? = null
- private lateinit var terminalViewModel: TerminalViewModel
+ private val terminalViewModel: TerminalViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater,
@@ -59,7 +60,6 @@
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- terminalViewModel = ViewModelProvider(this)[TerminalViewModel::class.java]
terminalView = view.findViewById(R.id.webview)
bootProgressView = view.findViewById(R.id.boot_progress)
initializeWebView()
@@ -79,19 +79,46 @@
terminalView.saveState(outState)
}
+ override fun onResume() {
+ super.onResume()
+ updateFocus()
+ }
+
private fun initializeWebView() {
terminalView.settings.databaseEnabled = true
terminalView.settings.domStorageEnabled = true
terminalView.settings.javaScriptEnabled = true
terminalView.settings.cacheMode = WebSettings.LOAD_DEFAULT
- terminalView.webChromeClient = WebChromeClient()
+ terminalView.webChromeClient = TerminalWebChromeClient()
terminalView.webViewClient = TerminalWebViewClient()
(activity as MainActivity).modifierKeysController.addTerminalView(terminalView)
terminalViewModel.terminalViews.add(terminalView)
}
+ private inner class TerminalWebChromeClient : WebChromeClient() {
+ override fun onReceivedTitle(view: WebView?, title: String?) {
+ super.onReceivedTitle(view, title)
+ title?.let { originalTitle ->
+ val ttydSuffix = " | login -f droid (localhost)"
+ val displayedTitle =
+ if (originalTitle.endsWith(ttydSuffix)) {
+ // When the session is created. The format of the title will be
+ // 'droid@localhost: ~ | login -f droid (localhost)'.
+ originalTitle.dropLast(ttydSuffix.length)
+ } else {
+ originalTitle
+ }
+
+ terminalViewModel.terminalTabs[id]
+ ?.customView
+ ?.findViewById<TextView>(R.id.tab_title)
+ ?.text = displayedTitle
+ }
+ }
+ }
+
private inner class TerminalWebViewClient : WebViewClient() {
private var loadFailed = false
private var requestId: Long = 0
@@ -148,6 +175,7 @@
terminalView.visibility = View.VISIBLE
terminalView.mapTouchToMouseEvent()
updateMainActivity()
+ updateFocus()
}
}
},
@@ -189,6 +217,12 @@
certificates = arrayOf<X509Certificate>(pke.certificate as X509Certificate)
}
+ private fun updateFocus() {
+ if (terminalViewModel.selectedTabViewId == id) {
+ terminalView.requestFocus()
+ }
+ }
+
companion object {
const val TAG: String = "VmTerminalApp"
}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalViewModel.kt b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalViewModel.kt
index 4a69f75..dd40143 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalViewModel.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalViewModel.kt
@@ -16,7 +16,10 @@
package com.android.virtualization.terminal
import androidx.lifecycle.ViewModel
+import com.google.android.material.tabs.TabLayout.Tab
class TerminalViewModel : ViewModel() {
val terminalViews: MutableSet<TerminalView> = mutableSetOf()
+ var selectedTabViewId: String? = null
+ val terminalTabs: MutableMap<String, Tab> = mutableMapOf()
}
diff --git a/android/TerminalApp/res/layout/tabitem_terminal.xml b/android/TerminalApp/res/layout/tabitem_terminal.xml
index 92e3802..9eba163 100644
--- a/android/TerminalApp/res/layout/tabitem_terminal.xml
+++ b/android/TerminalApp/res/layout/tabitem_terminal.xml
@@ -25,7 +25,7 @@
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_toStartOf="@id/tab_close_button"
- android:gravity="center"
+ android:gravity="center_vertical"
android:padding="8dp"
android:text="@string/tab_default_title"/>
diff --git a/android/virtmgr/src/aidl.rs b/android/virtmgr/src/aidl.rs
index 1c4c2eb..d7f68b8 100644
--- a/android/virtmgr/src/aidl.rs
+++ b/android/virtmgr/src/aidl.rs
@@ -597,9 +597,10 @@
config: &VirtualMachineConfig,
) -> binder::Result<(VmContext, Cid, PathBuf)> {
const NUM_ATTEMPTS: usize = 5;
+ let name = get_name(config);
for _ in 0..NUM_ATTEMPTS {
- let vm_context = GLOBAL_SERVICE.allocateGlobalVmContext(requester_debug_pid)?;
+ let vm_context = GLOBAL_SERVICE.allocateGlobalVmContext(name, requester_debug_pid)?;
let cid = vm_context.getCid()? as Cid;
let temp_dir: PathBuf = vm_context.getTemporaryDirectory()?.into();
@@ -797,9 +798,8 @@
.or_service_specific_exception(-1)?;
}
- // Check if files for payloads and bases are NOT coming from /vendor and /odm, as they may
- // have unstable interfaces.
- // TODO(b/316431494): remove once Treble interfaces are stabilized.
+ // Check if files for payloads and bases are on the same side of the Treble boundary as the
+ // calling process, as they may have unstable interfaces.
check_partitions_for_files(config, calling_partition).or_service_specific_exception(-1)?;
let zero_filler_path = temporary_directory.join("zero.img");
@@ -1053,6 +1053,14 @@
}
}
+/// Returns the name of the config
+fn get_name(config: &VirtualMachineConfig) -> &str {
+ match config {
+ VirtualMachineConfig::AppConfig(config) => &config.name,
+ VirtualMachineConfig::RawConfig(config) => &config.name,
+ }
+}
+
fn extract_vendor_hashtree_digest(config: &VirtualMachineConfig) -> Result<Option<Vec<u8>>> {
let VirtualMachineConfig::AppConfig(config) = config else {
return Ok(None);
diff --git a/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineDebugInfo.aidl b/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineDebugInfo.aidl
index 9f033b1..eb71028 100644
--- a/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineDebugInfo.aidl
+++ b/android/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineDebugInfo.aidl
@@ -19,6 +19,9 @@
/** Information about a running VM, for debug purposes only. */
parcelable VirtualMachineDebugInfo {
+ /** Name of the VM. */
+ String name;
+
/** The CID assigned to the VM. */
int cid;
diff --git a/android/virtualizationservice/aidl/android/system/virtualizationservice_internal/IVfioHandler.aidl b/android/virtualizationservice/aidl/android/system/virtualizationservice_internal/IVfioHandler.aidl
index 2cf4efd..4ded2a9 100644
--- a/android/virtualizationservice/aidl/android/system/virtualizationservice_internal/IVfioHandler.aidl
+++ b/android/virtualizationservice/aidl/android/system/virtualizationservice_internal/IVfioHandler.aidl
@@ -16,7 +16,6 @@
package android.system.virtualizationservice_internal;
import android.system.virtualizationservice.AssignableDevice;
-import android.system.virtualizationservice.VirtualMachineDebugInfo;
import android.system.virtualizationservice_internal.AtomVmBooted;
import android.system.virtualizationservice_internal.AtomVmCreationRequested;
import android.system.virtualizationservice_internal.AtomVmExited;
diff --git a/android/virtualizationservice/aidl/android/system/virtualizationservice_internal/IVirtualizationServiceInternal.aidl b/android/virtualizationservice/aidl/android/system/virtualizationservice_internal/IVirtualizationServiceInternal.aidl
index 4f549cb..3d4a813 100644
--- a/android/virtualizationservice/aidl/android/system/virtualizationservice_internal/IVirtualizationServiceInternal.aidl
+++ b/android/virtualizationservice/aidl/android/system/virtualizationservice_internal/IVirtualizationServiceInternal.aidl
@@ -39,7 +39,7 @@
* The resources will not be recycled as long as there is a strong reference
* to the returned object.
*/
- IGlobalVmContext allocateGlobalVmContext(int requesterDebugPid);
+ IGlobalVmContext allocateGlobalVmContext(String name, int requesterDebugPid);
/** Forwards a VmBooted atom to statsd. */
void atomVmBooted(in AtomVmBooted atom);
diff --git a/android/virtualizationservice/src/aidl.rs b/android/virtualizationservice/src/aidl.rs
index 62cede8..1646117 100644
--- a/android/virtualizationservice/src/aidl.rs
+++ b/android/virtualizationservice/src/aidl.rs
@@ -273,6 +273,7 @@
fn allocateGlobalVmContext(
&self,
+ name: &str,
requester_debug_pid: i32,
) -> binder::Result<Strong<dyn IGlobalVmContext>> {
check_manage_access()?;
@@ -281,7 +282,7 @@
let requester_debug_pid = requester_debug_pid as pid_t;
let state = &mut *self.state.lock().unwrap();
state
- .allocate_vm_context(requester_uid, requester_debug_pid)
+ .allocate_vm_context(name, requester_uid, requester_debug_pid)
.or_binder_exception(ExceptionCode::ILLEGAL_STATE)
}
@@ -311,6 +312,7 @@
.map(|vm| {
let vm = vm.lock().unwrap();
VirtualMachineDebugInfo {
+ name: vm.name.clone(),
cid: vm.cid as i32,
temporaryDirectory: vm.get_temp_dir().to_string_lossy().to_string(),
requesterUid: vm.requester_uid as i32,
@@ -665,6 +667,8 @@
#[derive(Debug, Default)]
struct GlobalVmInstance {
+ /// Name of the VM
+ name: String,
/// The unique CID assigned to the VM for vsock communication.
cid: Cid,
/// UID of the client who requested this VM instance.
@@ -760,6 +764,7 @@
fn allocate_vm_context(
&mut self,
+ name: &str,
requester_uid: uid_t,
requester_debug_pid: pid_t,
) -> Result<Strong<dyn IGlobalVmContext>> {
@@ -768,6 +773,7 @@
let cid = self.get_next_available_cid()?;
let instance = Arc::new(Mutex::new(GlobalVmInstance {
+ name: name.to_owned(),
cid,
requester_uid,
requester_debug_pid,
diff --git a/build/debian/fai_config/scripts/AVF/20-useradd b/build/debian/fai_config/scripts/AVF/20-useradd
index b92648a..2289a2a 100755
--- a/build/debian/fai_config/scripts/AVF/20-useradd
+++ b/build/debian/fai_config/scripts/AVF/20-useradd
@@ -2,3 +2,7 @@
$ROOTCMD useradd -m -u 1000 -N -G sudo,video,render -s /usr/bin/bash droid
$ROOTCMD echo 'droid ALL=(ALL) NOPASSWD:ALL' >> $target/etc/sudoers
+$ROOTCMD cat >> $target/home/droid/.bashrc <<EOF
+# Show title of current running command
+trap 'echo -ne "\e]0;\$BASH_COMMAND\007"' DEBUG
+EOF
diff --git a/guest/microdroid_manager/microdroid_manager.rc b/guest/microdroid_manager/microdroid_manager.rc
index 9fa8a9d..48cc6d7 100644
--- a/guest/microdroid_manager/microdroid_manager.rc
+++ b/guest/microdroid_manager/microdroid_manager.rc
@@ -8,6 +8,7 @@
# CAP_SYS_BOOT is required to exec kexecload from microdroid_manager
# CAP_SETPCAP is required to allow microdroid_manager to drop capabilities
# before executing the payload
- capabilities AUDIT_CONTROL SYS_ADMIN SYS_BOOT SETPCAP SETUID SETGID
+ # CAP_SYS_NICE is required for microdroid_manager to adjust priority of the payload
+ capabilities AUDIT_CONTROL SYS_ADMIN SYS_BOOT SETPCAP SETUID SETGID SYS_NICE
user root
socket vm_payload_service stream 0666 system system
diff --git a/guest/microdroid_manager/src/main.rs b/guest/microdroid_manager/src/main.rs
index 4537834..a95bcb2 100644
--- a/guest/microdroid_manager/src/main.rs
+++ b/guest/microdroid_manager/src/main.rs
@@ -710,7 +710,21 @@
info!("notifying payload started");
service.notifyPayloadStarted()?;
- let exit_status = command.spawn()?.wait()?;
+ let mut payload_process = command.spawn().context("failed to spawn payload process")?;
+ info!("payload pid = {:?}", payload_process.id());
+
+ // SAFETY: setpriority doesn't take any pointers
+ unsafe {
+ let ret = libc::setpriority(libc::PRIO_PROCESS, payload_process.id(), -20);
+ if ret != 0 {
+ error!(
+ "failed to adjust priority of the payload: {:#?}",
+ std::io::Error::last_os_error()
+ );
+ }
+ }
+
+ let exit_status = payload_process.wait()?;
match exit_status.code() {
Some(exit_code) => Ok(exit_code),
None => Err(match exit_status.signal() {
diff --git a/guest/pvmfw/README.md b/guest/pvmfw/README.md
index 652ca90..c7f3dd6 100644
--- a/guest/pvmfw/README.md
+++ b/guest/pvmfw/README.md
@@ -147,6 +147,10 @@
| offset = (FOURTH - HEAD) |
| size = (FOURTH_END - FOURTH) |
+-------------------------------+
+| [Entry 4] | <-- Entry 4 is present since version 1.3
+| offset = (FIFTH - HEAD) |
+| size = (FIFTH_END - FIFTH) |
++-------------------------------+
| ... |
+-------------------------------+
| [Entry n] |
@@ -168,7 +172,11 @@
| {Fourth blob: VM reference DT}|
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ <-- FOURTH_END
| (Padding to 8-byte alignment) |
-+===============================+
++===============================+ <-- FIFTH
+| {Fifth blob: Reserved Memory} |
++~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ <-- FIFTH_END
+| (Padding to 8-byte alignment) |
++===============================+ <-- FIFTH
| ... |
+===============================+ <-- TAIL
```
@@ -238,6 +246,31 @@
[secretkeeper_key]: https://android.googlesource.com/platform/system/secretkeeper/+/refs/heads/main/README.md#secretkeeper-public-key
[vendor_hashtree_digest]: ../../build/microdroid/README.md#verification-of-vendor-image
+#### Version 1.3 {#pvmfw-data-v1-3}
+
+In version 1.3, a fifth blob is added.
+
+- entry 4, if present, contains potentially confidential data to be passed to
+ specific guests identified from their VM name. If the data is confidential,
+ this feature should only be used with guests using a fixed rollback
+ protection mechanism to prevent rollback attacks from a malicious host. Data
+ is passed as a reserved-memory region through the device tree with the
+ provided properties at an address which is implementation defined. Multiple
+ regions may be passed to the same guest. The format is as follows.
+
+ ```rust
+ #[repr(C)]
+ struct ReservedMemConfigEntry<const N: usize> {
+ /// The number of headers contained in this blob.
+ count: u32,
+ /// The [reserved memory headers](src/reserved_mem.rs) describing the passed data.
+ headers: [RMemHeader; N]
+ /// The actual data being passed. The reserved memory headers point to
+ /// offsets within this array.
+ data: [u8],
+ }
+ ```
+
#### Virtual Platform DICE Chain Handover
The format of the DICE chain entry mentioned above, compatible with the
diff --git a/guest/trusty/test_vm/AndroidTest.xml b/guest/trusty/test_vm/AndroidTest.xml
index 925b43c..43d9ef8 100644
--- a/guest/trusty/test_vm/AndroidTest.xml
+++ b/guest/trusty/test_vm/AndroidTest.xml
@@ -15,10 +15,10 @@
limitations under the License.
-->
<configuration description="Runs {MODULE}">
- <!-- object type="module_controller" class="com.android.tradefed.testtype.suite.module.CommandSuccessModuleController" -->
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.CommandSuccessModuleController">
<!--Skip the test when trusty VM is not enabled. -->
- <!--option name="run-command" value="getprop trusty.test_vm.nonsecure_vm_ready | grep 1" /-->
- <!--/object-->
+ <option name="run-command" value="getprop trusty.security_vm.enabled | grep 1" />
+ </object>
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
<!-- Target Preparers - Run Shell Commands -->
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
@@ -38,13 +38,19 @@
<option name="run-command" value="start storageproxyd_test_vm" />
<option name="teardown-command" value="stop storageproxyd_test_vm" />
<option name="teardown-command" value="killall storageproxyd_test_vm || true" />
+ <!--option name="teardown-command" value="rm -rf /data/local/trusty_test_vm"/-->
</target_preparer>
<test class="com.android.tradefed.testtype.binary.ExecutableTargetTest" >
<option name="parse-gtest" value="true" />
<option name="abort-if-device-lost" value="true"/>
<option name="abort-if-root-lost" value="true" />
<option name="per-binary-timeout" value="10m" />
+ <option name="test-command-line" key="com.android.trusty.rust.authmgr_be_lib.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.rust.authmgr_be_lib.test"/>
<option name="test-command-line" key="com.android.trusty.rust.hwcryptokey_test.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.rust.hwcryptokey_test.test"/>
<option name="test-command-line" key="com.android.trusty.rust.storage_unittest_aidl.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.rust.storage_unittest_aidl.test"/>
</test>
+ <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+ <option name="directory-keys" value="/data/local/tmp/trusty_test_vm/logs" />
+ <option name="clean-up" value="false"/>
+ </metrics_collector>
</configuration>
diff --git a/guest/trusty/test_vm/README.md b/guest/trusty/test_vm/README.md
index 71368b5..81382c5 100644
--- a/guest/trusty/test_vm/README.md
+++ b/guest/trusty/test_vm/README.md
@@ -11,3 +11,16 @@
The Trusty test_vm also includes the VINTF test which allows to check the vendor
support of the Trusted HALs (version and API hash), against the expected
compatibility matrix for a given Android Dessert Release.
+
+### instructions
+
+`atest -s <device-serial-port> VtsSeeHalTargetTest
+
+### test_vm console
+
+The test_vm console can be retrieved from `/data/local/tmp/trusty_test_vm/logs/console.log`.
+The script `trusty-vm-laucher.sh` uses `/apex/com.android.virt/bin/vm run` with the option
+`--console` to store the console log.
+
+This log can be consulted when the tests are running and will be uploaded
+by the Tradefed FilePullerLogCollector runner (see AndroidTest.xml).
diff --git a/guest/trusty/test_vm/TEST_MAPPING b/guest/trusty/test_vm/TEST_MAPPING
deleted file mode 100644
index aa9d65d..0000000
--- a/guest/trusty/test_vm/TEST_MAPPING
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "trusty_test_vm_presubmit": [
- ],
- "trusty_test_vm_postsubmit": [
- {
- "name": "TrustyTestVM_UnitTests"
- }
- ]
-}
diff --git a/guest/trusty/test_vm/trusty-vm-launcher.sh b/guest/trusty/test_vm/trusty-vm-launcher.sh
index cb8661f..079a66a 100755
--- a/guest/trusty/test_vm/trusty-vm-launcher.sh
+++ b/guest/trusty/test_vm/trusty-vm-launcher.sh
@@ -14,4 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-/apex/com.android.virt/bin/vm run /data/local/tmp/trusty_test_vm/trusty-test_vm-config.json
+mkdir -p /data/local/tmp/trusty_test_vm/logs || true
+/apex/com.android.virt/bin/vm run \
+ --console /data/local/tmp/trusty_test_vm/logs/console.log \
+ /data/local/tmp/trusty_test_vm/trusty-test_vm-config.json
diff --git a/guest/trusty/test_vm_os/AndroidTest.xml b/guest/trusty/test_vm_os/AndroidTest.xml
index be5c467..5adafff 100644
--- a/guest/trusty/test_vm_os/AndroidTest.xml
+++ b/guest/trusty/test_vm_os/AndroidTest.xml
@@ -15,10 +15,10 @@
limitations under the License.
-->
<configuration description="Runs {MODULE}">
- <!-- object type="module_controller" class="com.android.tradefed.testtype.suite.module.CommandSuccessModuleController" -->
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.CommandSuccessModuleController">
<!--Skip the test when trusty VM is not enabled. -->
- <!--option name="run-command" value="getprop trusty.test_vm.nonsecure_vm_ready | grep 1" /-->
- <!--/object-->
+ <option name="run-command" value="getprop trusty.security_vm.enabled | grep 1" />
+ </object>
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
<!-- Target Preparers - Run Shell Commands -->
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
@@ -38,6 +38,7 @@
<option name="run-command" value="start storageproxyd_test_vm_os" />
<option name="teardown-command" value="stop storageproxyd_test_vm_os" />
<option name="teardown-command" value="killall storageproxyd_test_vm_os || true" />
+ <!--option name="teardown-command" value="rm -rf /data/local/trusty_test_vm_os"/-->
</target_preparer>
<test class="com.android.tradefed.testtype.binary.ExecutableTargetTest" >
<option name="parse-gtest" value="true" />
@@ -79,4 +80,10 @@
<option name="test-command-line" key="com.android.trusty.rust.binder_rpc_test.test" value="/data/local/tmp/trusty_test_vm_os/trusty-ut-ctrl.sh com.android.trusty.rust.binder_rpc_test.test"/>
<option name="test-command-line" key="com.android.trusty.binder.test" value="/data/local/tmp/trusty_test_vm_os/trusty-ut-ctrl.sh com.android.trusty.binder.test"/>
</test>
+ <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+ <option name="directory-keys" value="/data/local/tmp/trusty_test_vm_os/logs" />
+ <option name="collect-on-run-ended-only" value="true" />
+ <option name="clean-up" value="true"/>
+ <option name="collect-on-run-ended-only" value="false" />
+ </metrics_collector>
</configuration>
diff --git a/guest/trusty/test_vm_os/README.md b/guest/trusty/test_vm_os/README.md
index 4d65d9f..b37a4da 100644
--- a/guest/trusty/test_vm_os/README.md
+++ b/guest/trusty/test_vm_os/README.md
@@ -5,3 +5,6 @@
- Trusty kernel OS test
- Trusty/Binder IPC tests
- Trusty user-space tests for service TAs (DT tree for example)
+
+
+see instructions at [test_vm/README.md](../test_vm/README.md)
diff --git a/guest/trusty/test_vm_os/TEST_MAPPING b/guest/trusty/test_vm_os/TEST_MAPPING
deleted file mode 100644
index 1506720..0000000
--- a/guest/trusty/test_vm_os/TEST_MAPPING
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "trusty_test_vm_presubmit": [
- ],
- "trusty_test_vm_postsubmit": [
- {
- "name": "TrustyVMOS_UnitTests"
- }
- ]
-}
diff --git a/guest/trusty/test_vm_os/trusty-vm-launcher.sh b/guest/trusty/test_vm_os/trusty-vm-launcher.sh
index 497b188..bc256ed 100755
--- a/guest/trusty/test_vm_os/trusty-vm-launcher.sh
+++ b/guest/trusty/test_vm_os/trusty-vm-launcher.sh
@@ -14,4 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-/apex/com.android.virt/bin/vm run /data/local/tmp/trusty_test_vm_os/trusty-test_vm-config.json
+mkdir -p /data/local/tmp/trusty_test_vm_os/logs || true
+/apex/com.android.virt/bin/vm run \
+ --console /data/local/tmp/trusty_test_vm_os/logs/console.log \
+ /data/local/tmp/trusty_test_vm_os/trusty-test_vm-config.json
diff --git a/libs/dice/open_dice/src/error.rs b/libs/dice/open_dice/src/error.rs
index c9eb5cc..87d463e 100644
--- a/libs/dice/open_dice/src/error.rs
+++ b/libs/dice/open_dice/src/error.rs
@@ -33,6 +33,8 @@
UnsupportedKeyAlgorithm(coset::iana::Algorithm),
/// A failed fallible allocation. Used in no_std environments.
MemoryAllocationError,
+ /// DICE chain not found in artifacts.
+ DiceChainNotFound,
}
/// This makes `DiceError` accepted by anyhow.
@@ -51,6 +53,7 @@
write!(f, "Unsupported key algorithm: {algorithm:?}")
}
Self::MemoryAllocationError => write!(f, "Memory allocation failed"),
+ Self::DiceChainNotFound => write!(f, "DICE chain not found in artifacts"),
}
}
}
diff --git a/libs/dice/open_dice/src/retry.rs b/libs/dice/open_dice/src/retry.rs
index d793218..2b7b740 100644
--- a/libs/dice/open_dice/src/retry.rs
+++ b/libs/dice/open_dice/src/retry.rs
@@ -17,7 +17,7 @@
//! of this buffer may fail and callers will see Error::MemoryAllocationError.
//! When running with std, allocation may fail.
-use crate::bcc::{bcc_format_config_descriptor, bcc_main_flow, DiceConfigValues};
+use crate::bcc::{bcc_format_config_descriptor, bcc_main_flow, BccHandover, DiceConfigValues};
use crate::dice::{
dice_main_flow, Cdi, CdiValues, DiceArtifacts, InputValues, CDI_SIZE, PRIVATE_KEY_SEED_SIZE,
PRIVATE_KEY_SIZE,
@@ -60,6 +60,20 @@
}
}
+impl TryFrom<BccHandover<'_>> for OwnedDiceArtifacts {
+ type Error = DiceError;
+
+ fn try_from(artifacts: BccHandover<'_>) -> Result<Self> {
+ let cdi_attest = artifacts.cdi_attest().to_vec().try_into().unwrap();
+ let cdi_seal = artifacts.cdi_seal().to_vec().try_into().unwrap();
+ let bcc = artifacts
+ .bcc()
+ .map(|bcc_slice| bcc_slice.to_vec())
+ .ok_or(DiceError::DiceChainNotFound)?;
+ Ok(OwnedDiceArtifacts { cdi_values: CdiValues { cdi_attest, cdi_seal }, bcc })
+ }
+}
+
/// Retries the given function with bigger measured buffer size.
fn retry_with_measured_buffer<F>(mut f: F) -> Result<Vec<u8>>
where