genpolicy: enable storage checks

This patch
 - adds condition to add container image layers as storages
 - enable storage checks
 - fix CI policy test cases
 - update genpolicy-settings.json to enable storage checks
 - remove storage object addition in container image parsing

Signed-off-by: Archana Choudhary <archana1@microsoft.com>
This commit is contained in:
Archana Choudhary 2025-05-22 14:37:26 +00:00
parent 5b1459e623
commit 9ebbc08d70
5 changed files with 63 additions and 36 deletions

View File

@ -155,7 +155,7 @@
"emptyDir": {
"mount_type": "local",
"mount_source": "^$(cpath)/$(sandbox-id)/rootfs/local/",
"mount_point": "^$(cpath)/$(sandbox-id)/local/",
"mount_point": "^$(cpath)/$(sandbox-id)/rootfs/local/",
"driver": "local",
"source": "local",
"fstype": "local",
@ -315,7 +315,8 @@
"CAP_PERFMON",
"CAP_BPF",
"CAP_CHECKPOINT_RESTORE"
]
],
"image_layer_verification" : "none"
},
"kata_config": {
"confidential_guest": false,

View File

@ -671,8 +671,7 @@ allow_by_bundle_or_sandbox_id(p_oci, i_oci, p_storages, i_storages) if {
count(p_matches) == count(input.OCI.Mounts)
# TODO: enable allow_storages() after fixing https://github.com/kata-containers/kata-containers/issues/8833
# allow_storages(p_storages, i_storages, bundle_id, sandbox_id)
allow_storages(p_storages, i_storages, bundle_id, sandbox_id)
print("allow_by_bundle_or_sandbox_id: true")
}
@ -1038,17 +1037,9 @@ allow_storages(p_storages, i_storages, bundle_id, sandbox_id) if {
p_count == i_count
# Get the container image layer IDs and verity root hashes, from the "overlayfs" storage.
some overlay_storage in p_storages
overlay_storage.driver == "overlayfs"
print("allow_storages: overlay_storage =", overlay_storage)
count(overlay_storage.options) == 2
layer_ids := split(overlay_storage.options[0], ":")
print("allow_storages: layer_ids =", layer_ids)
root_hashes := split(overlay_storage.options[1], ":")
print("allow_storages: root_hashes =", root_hashes)
image_info := allow_container_image_storage(p_storages)
layer_ids := image_info.layer_ids
root_hashes := image_info.root_hashes
every i_storage in i_storages {
allow_storage(p_storages, i_storage, bundle_id, sandbox_id, layer_ids, root_hashes)
@ -1057,6 +1048,23 @@ allow_storages(p_storages, i_storages, bundle_id, sandbox_id) if {
print("allow_storages: true")
}
# Currently, Image Layer Integrity Verification through Policy is only required for Guest VMs
# that use container image layers provided as dm-verity-protected block device images created on the Host.
allow_container_image_storage(p_storages) = { "layer_ids": [], "root_hashes": [] } {
policy_data.common.image_layer_verification != "host-tarfs-dm-verity"
}
allow_container_image_storage(p_storages) = { "layer_ids": layer_ids, "root_hashes": root_hashes } {
policy_data.common.image_layer_verification == "host-tarfs-dm-verity"
some overlay_storage in p_storages
overlay_storage.driver == "overlayfs"
count(overlay_storage.options) == 2
layer_ids := split(overlay_storage.options[0], ":")
root_hashes := split(overlay_storage.options[1], ":")
}
allow_storage(p_storages, i_storage, bundle_id, sandbox_id, layer_ids, root_hashes) if {
some p_storage in p_storages
@ -1066,15 +1074,44 @@ allow_storage(p_storages, i_storage, bundle_id, sandbox_id, layer_ids, root_hash
p_storage.driver == i_storage.driver
p_storage.driver_options == i_storage.driver_options
p_storage.fs_group == i_storage.fs_group
p_storage.fstype == i_storage.fstype
allow_storage_source(p_storage, i_storage, bundle_id)
allow_storage_options(p_storage, i_storage, layer_ids, root_hashes)
allow_mount_point(p_storage, i_storage, bundle_id, sandbox_id, layer_ids)
# TODO: validate the source field too.
print("allow_storage: true")
}
allow_storage_source(p_storage, i_storage, bundle_id) {
print("allow_storage_source 1: start")
p_storage.source == i_storage.source
print("allow_storage_source 1: true")
}
allow_storage_source(p_storage, i_storage, bundle_id) {
print("allow_storage_source 2: start")
source1 := p_storage.source
source2 := replace(source1, "$(sfprefix)", policy_data.common.sfprefix)
source3 := replace(source2, "$(cpath)", policy_data.common.cpath)
source4 := replace(source3, "$(bundle-id)", bundle_id)
print("allow_storage_source 2: source =", source4)
regex.match(source4, i_storage.source)
print("allow_storage_source 2: true")
}
allow_storage_source(p_storage, i_storage, bundle_id) {
print("allow_storage_source 3: start")
p_storage.driver == "overlayfs"
i_storage.source == "none"
print("allow_storage_source 3: true")
}
allow_storage_options(p_storage, i_storage, layer_ids, root_hashes) if {
print("allow_storage_options 1: start")

View File

@ -375,7 +375,6 @@ fn get_downward_api_mount(yaml_mount: &pod::VolumeMount, p_mounts: &mut Vec<poli
pub fn get_image_mount_and_storage(
settings: &settings::Settings,
p_mounts: &mut Vec<policy::KataMount>,
storages: &mut Vec<agent::Storage>,
destination: &str,
) {
// https://github.com/kubernetes/examples/blob/master/cassandra/image/Dockerfile
@ -404,17 +403,6 @@ pub fn get_image_mount_and_storage(
settings_image
);
storages.push(agent::Storage {
driver: settings_image.driver.clone(),
driver_options: Vec::new(),
source: settings_image.source.clone(),
fstype: settings_image.fstype.clone(),
options: settings_image.options.clone(),
mount_point: destination_string.clone(),
fs_group: protobuf::MessageField::none(),
special_fields: ::protobuf::SpecialFields::new(),
});
let file_name = Path::new(&destination_string).file_name().unwrap();
let name = OsString::from(file_name).into_string().unwrap();
let source = format!("{}{name}$", &settings_image.mount_source);

View File

@ -418,6 +418,9 @@ pub struct CommonData {
/// Default capabilities for a privileged container.
pub privileged_caps: Vec<String>,
/// Parse Container image as a storage object
pub image_layer_verification: String,
}
/// Configuration from "kubectl config".
@ -615,7 +618,10 @@ impl AgentPolicy {
let image_layers = yaml_container.registry.get_image_layers();
let mut storages = Default::default();
get_image_layer_storages(&mut storages, &image_layers, &root);
const HOST_TARFS_DM_VERITY: &str = "host-tarfs-dm-verity";
if self.config.settings.common.image_layer_verification == HOST_TARFS_DM_VERITY {
get_image_layer_storages(&mut storages, &image_layers, &root);
}
resource.get_container_mounts_and_storages(
&mut mounts,
&mut storages,

View File

@ -313,12 +313,7 @@ pub fn get_container_mounts_and_storages(
for volume in volumes {
debug!("get_container_mounts_and_storages: {:?}", &volume);
mount_and_storage::get_image_mount_and_storage(
settings,
policy_mounts,
storages,
volume.0,
);
mount_and_storage::get_image_mount_and_storage(settings, policy_mounts, volume.0);
}
}
}