From 5c8170dbb9005e178b1e1c2275312e17a8cb9ec0 Mon Sep 17 00:00:00 2001 From: "alex.lyn" Date: Fri, 13 Jun 2025 17:30:23 +0800 Subject: [PATCH] runtime-rs: Handle initdata block device config during sandbox start Retrieve the Initdata string content from the security_info of the Configuration. Based on the Protection Platform type, calculate the digest of the Initdata. Write the Initdata content to the block device. Subsequently, construct the BlockConfig based on this block device information. Signed-off-by: alex.lyn --- .../runtimes/virt_container/src/sandbox.rs | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs b/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs index bf504f394b..14afb19a10 100644 --- a/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs +++ b/src/runtime-rs/crates/runtimes/virt_container/src/sandbox.rs @@ -37,13 +37,19 @@ use kata_types::capabilities::CapabilityBits; use kata_types::config::hypervisor::Hypervisor as HypervisorConfig; use kata_types::config::hypervisor::HYPERVISOR_NAME_CH; use kata_types::config::TomlConfig; +use kata_types::initdata::{calculate_initdata_digest, ProtectedPlatform}; use oci_spec::runtime as oci; use persist::{self, sandbox_persist::Persist}; use protobuf::SpecialFields; +use resource::coco_data::initdata::{ + InitDataConfig, KATA_INIT_DATA_IMAGE, KATA_SHARED_INIT_DATA_PATH, +}; +use resource::coco_data::initdata_block; use resource::manager::ManagerArgs; use resource::network::{dan_config_path, DanNetworkConfig, NetworkConfig, NetworkWithNetNsConfig}; use resource::{ResourceConfig, ResourceManager}; use runtime_spec as spec; +use std::path::Path; use std::sync::Arc; use strum::Display; use tokio::sync::{mpsc::Sender, Mutex, RwLock}; @@ -157,6 +163,19 @@ impl VirtSandbox { resource_configs.push(vm_rootfs); } + // prepare protection device config + let _init_data = if let Some(initdata) = self + .prepare_initdata_device_config(&self.hypervisor.hypervisor_config().await) + .await + .context("failed to prepare initdata device config")? + { + resource_configs.push(ResourceConfig::InitData(initdata.0)); + + Some(initdata.1) + } else { + None + }; + // prepare protection device config if let Some(protection_dev_config) = self .prepare_protection_device_config(&self.hypervisor.hypervisor_config().await) @@ -411,6 +430,55 @@ impl VirtSandbox { } } + async fn prepare_initdata_device_config( + &self, + hypervisor_config: &HypervisorConfig, + ) -> Result> { + let initdata = hypervisor_config.security_info.initdata.clone(); + if initdata.is_empty() { + return Ok(None); + } + info!(sl!(), "Init Data Content String: {:?}", &initdata); + let available_protection = available_guest_protection()?; + info!( + sl!(), + "sandbox: available protection: {:?}", available_protection + ); + let initdata_digest = match available_protection { + GuestProtection::Tdx => calculate_initdata_digest(&initdata, ProtectedPlatform::Tdx)?, + GuestProtection::Snp(_details) => { + calculate_initdata_digest(&initdata, ProtectedPlatform::Snp)? + } + // TODO: there's more `GuestProtection` types to be supported. + _ => return Ok(None), + }; + info!( + sl!(), + "calculate initdata: {:?} with initdata digest {:?}", &initdata, &initdata_digest + ); + + // initdata within compressed rawblock + let image_path = Path::new(KATA_SHARED_INIT_DATA_PATH) + .join(&self.sid) + .join(KATA_INIT_DATA_IMAGE); + initdata_block::push_data(&image_path, &initdata)?; + info!( + sl!(), + "initdata push data into compressed block: {:?}", &image_path + ); + let block_driver = &hypervisor_config.boot_info.vm_rootfs_driver; + let block_config = BlockConfig { + path_on_host: image_path.display().to_string(), + is_readonly: true, + driver_option: block_driver.clone(), + ..Default::default() + }; + let initdata_config = InitDataConfig(block_config, initdata_digest); + info!(sl!(), "initdata config: {:?}", initdata_config.clone()); + + Ok(Some(initdata_config)) + } + fn has_prestart_hooks( &self, prestart_hooks: &[oci::Hook],