agent: Support trusted ephemeral data storage

This modifies the virtio-blk handler to handle trusted ephemeral storage
requests coming from the shim.

When the shim sends a storage with confidential=true and ephemeral=true, the
agent calls into the CDH to encrypt and format the block device.

Signed-off-by: Aurélien Bombo <abombo@microsoft.com>
This commit is contained in:
Aurélien Bombo
2025-01-15 15:59:34 -06:00
parent c8609bb857
commit a8ddcb2c4b

View File

@@ -5,7 +5,7 @@
// //
use std::fs; use std::fs;
use std::os::unix::fs::PermissionsExt; use std::os::unix::fs::{MetadataExt, PermissionsExt};
use std::path::Path; use std::path::Path;
use std::str::FromStr; use std::str::FromStr;
use std::sync::Arc; use std::sync::Arc;
@@ -16,6 +16,7 @@ use kata_types::device::{
DRIVER_SCSI_TYPE, DRIVER_SCSI_TYPE,
}; };
use kata_types::mount::StorageDevice; use kata_types::mount::StorageDevice;
use nix::sys::stat::{major, minor};
use protocols::agent::Storage; use protocols::agent::Storage;
use tracing::instrument; use tracing::instrument;
@@ -28,8 +29,8 @@ use crate::device::block_device_handler::{
}; };
use crate::device::nvdimm_device_handler::wait_for_pmem_device; use crate::device::nvdimm_device_handler::wait_for_pmem_device;
use crate::device::scsi_device_handler::get_scsi_device_name; use crate::device::scsi_device_handler::get_scsi_device_name;
use crate::pci;
use crate::storage::{common_storage_handler, new_device, StorageContext, StorageHandler}; use crate::storage::{common_storage_handler, new_device, StorageContext, StorageHandler};
use crate::{confidential_data_hub, pci, AGENT_CONFIG};
#[derive(Debug)] #[derive(Debug)]
pub struct VirtioBlkMmioHandler {} pub struct VirtioBlkMmioHandler {}
@@ -73,6 +74,8 @@ impl StorageHandler for VirtioBlkPciHandler {
mut storage: Storage, mut storage: Storage,
ctx: &mut StorageContext, ctx: &mut StorageContext,
) -> Result<Arc<dyn StorageDevice>> { ) -> Result<Arc<dyn StorageDevice>> {
let dev_num;
// If hot-plugged, get the device node path based on the PCI path // If hot-plugged, get the device node path based on the PCI path
// otherwise use the virt path provided in Storage Source // otherwise use the virt path provided in Storage Source
if storage.source.starts_with("/dev") { if storage.source.starts_with("/dev") {
@@ -82,14 +85,46 @@ impl StorageHandler for VirtioBlkPciHandler {
if mode & libc::S_IFBLK == 0 { if mode & libc::S_IFBLK == 0 {
return Err(anyhow!("Invalid device {}", &storage.source)); return Err(anyhow!("Invalid device {}", &storage.source));
} }
let dev_id = metadata.rdev();
dev_num = format!("{}:{}", major(dev_id), minor(dev_id));
} else { } else {
let pcipath = pci::Path::from_str(&storage.source)?; let pcipath = pci::Path::from_str(&storage.source)?;
let dev_path = get_virtio_blk_pci_device_name(ctx.sandbox, &pcipath).await?; let dev_path = get_virtio_blk_pci_device_name(ctx.sandbox, &pcipath).await?;
storage.source = dev_path; storage.source = dev_path;
let metadata = fs::metadata(&storage.source)
.context(format!("get metadata on file {:?}", &storage.source))?;
let dev_id = metadata.rdev();
dev_num = format!("{}:{}", major(dev_id), minor(dev_id));
} }
let path = common_storage_handler(ctx.logger, &storage)?; let confidential = storage
new_device(path) .driver_options
.contains(&"confidential=true".to_string());
let ephemeral = storage
.driver_options
.contains(&"ephemeral=true".to_string());
if confidential && ephemeral {
let integrity = AGENT_CONFIG.secure_storage_integrity.to_string();
let options = std::collections::HashMap::from([
("deviceId".to_string(), dev_num),
("encryptType".to_string(), "LUKS".to_string()),
("dataIntegrity".to_string(), integrity),
]);
confidential_data_hub::secure_mount(
"BlockDevice",
&options,
vec![],
&storage.mount_point,
)
.await?;
new_device(storage.mount_point)
} else {
let path = common_storage_handler(ctx.logger, &storage)?;
new_device(path)
}
} }
} }