genpolicy: fs_group for encrypted emptyDir volumes

The shim uses Storage.fs_group on block/scsi encrypted emptyDir while
genpolicy used fsgid= in options and null fs_group, leading to
denying CreateContainerRequest when using block-encrypted emptyDir in
combination with fsGroup. Thus, emit fs_group in that scenario and keep
fsgid= for the existing shared-fs/local emptyDir behavior.

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
This commit is contained in:
Manuel Huber
2026-03-25 12:02:47 -07:00
parent 53f273da5d
commit 5ff71d86ca
2 changed files with 36 additions and 15 deletions

View File

@@ -114,10 +114,12 @@ pub fn get_mount_and_storage(
if let Some(emptyDir) = &yaml_volume.emptyDir {
let settings_volumes = &settings.volumes;
let volume = match emptyDir.medium.as_deref() {
Some("Memory") => &settings_volumes.emptyDir_memory,
_ if settings.cluster_config.encrypted_emptydir => &settings_volumes.emptyDir_encrypted,
_ => &settings_volumes.emptyDir,
let (volume, block_encrypted_emptydir) = match emptyDir.medium.as_deref() {
Some("Memory") => (&settings_volumes.emptyDir_memory, false),
_ if settings.cluster_config.encrypted_emptydir => {
(&settings_volumes.emptyDir_encrypted, true)
}
_ => (&settings_volumes.emptyDir, false),
};
get_empty_dir_mount_and_storage(
@@ -127,6 +129,7 @@ pub fn get_mount_and_storage(
yaml_mount,
volume,
pod_security_context,
block_encrypted_emptydir,
);
} else if yaml_volume.persistentVolumeClaim.is_some() || yaml_volume.azureFile.is_some() {
get_shared_bind_mount(yaml_mount, p_mounts, "rprivate", "rw");
@@ -150,18 +153,36 @@ fn get_empty_dir_mount_and_storage(
yaml_mount: &pod::VolumeMount,
settings_empty_dir: &settings::EmptyDirVolume,
pod_security_context: &Option<pod::PodSecurityContext>,
block_encrypted_emptydir: bool,
) {
debug!("Settings emptyDir: {:?}", settings_empty_dir);
if yaml_mount.subPathExpr.is_none() {
let mut options = settings_empty_dir.options.clone();
if let Some(gid) = pod_security_context.as_ref().and_then(|sc| sc.fsGroup) {
// This matches the runtime behavior of only setting the fsgid if the mountpoint GID is not 0.
// https://github.com/kata-containers/kata-containers/blob/b69da5f3ba8385c5833b31db41a846a203812675/src/runtime/virtcontainers/kata_agent.go#L1602-L1607
if gid != 0 {
options.push(format!("fsgid={gid}"));
// Pod fsGroup in policy must mirror how the shim encodes it on Storage:
// - block-encrypted host emptyDirs become virtio-blk/scsi volumes; the runtime sets
// Storage.fs_group from mount metadata (handleDeviceBlockVolume in kata_agent.go).
// - shared-fs / guest-local emptyDirs use Storage.options: the runtime appends
// fsgid=<host GID> when the volume is not root-owned (handleEphemeralStorage and
// handleLocalStorage in kata_agent.go). Genpolicy uses pod fsGroup when non-zero as
// the usual kubelet-applied GID for that stat.
let pod_gid = pod_security_context.as_ref().and_then(|sc| sc.fsGroup);
let fs_group = if block_encrypted_emptydir {
match pod_gid {
Some(gid) if gid != 0 => protobuf::MessageField::some(agent::FSGroup {
group_id: gid as u32,
..Default::default()
}),
_ => protobuf::MessageField::none(),
}
}
} else {
if let Some(gid) = pod_gid {
if gid != 0 {
options.push(format!("fsgid={gid}"));
}
}
protobuf::MessageField::none()
};
storages.push(agent::Storage {
driver: settings_empty_dir.driver.clone(),
driver_options: settings_empty_dir.driver_options.clone(),
@@ -173,7 +194,7 @@ fn get_empty_dir_mount_and_storage(
} else {
settings_empty_dir.mount_point.clone()
},
fs_group: protobuf::MessageField::none(),
fs_group,
shared: settings_empty_dir.shared,
special_fields: ::protobuf::SpecialFields::new(),
});

View File

@@ -345,12 +345,12 @@
"driver_options": [
"encryption_key=ephemeral"
],
"fs_group": null,
"fs_group": {
"group_id": 1000
},
"fstype": "ext4",
"mount_point": "/run/kata-containers/sandbox/storage/MDAvMDA=",
"options": [
"fsgid=1000"
],
"options": [],
"source": "00/00",
"shared": true
}