From 3acb618f6bae4f5ccaff7bdc59659c3bf6339879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Bombo?= Date: Tue, 27 Jan 2026 17:04:19 -0600 Subject: [PATCH] genpolicy: Assume `disable_guest_empty_dir = true` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This option should be removed for 4.0, so we don't handle `false`. Signed-off-by: Aurélien Bombo --- src/runtime/virtcontainers/fs_share_linux.go | 7 +- src/tools/genpolicy/src/mount_and_storage.rs | 126 +++++++++++++++---- 2 files changed, 101 insertions(+), 32 deletions(-) diff --git a/src/runtime/virtcontainers/fs_share_linux.go b/src/runtime/virtcontainers/fs_share_linux.go index 6ad9737fe3..36a89e8a57 100644 --- a/src/runtime/virtcontainers/fs_share_linux.go +++ b/src/runtime/virtcontainers/fs_share_linux.go @@ -332,11 +332,10 @@ func (f *FilesystemShare) ShareFile(ctx context.Context, c *Container, m *Mount) if !caps.IsFsSharingSupported() { if mustCopyEmptyDir { f.srcGuestMapLock.Lock() + defer f.srcGuestMapLock.Unlock() if guestPath, ok := f.srcGuestMap[m.Source]; ok { - f.srcGuestMapLock.Unlock() return &SharedFile{guestPath: guestPath}, nil } - f.srcGuestMapLock.Unlock() } f.Logger().Debug("filesystem sharing is not supported, files will be copied") @@ -420,9 +419,7 @@ func (f *FilesystemShare) ShareFile(ctx context.Context, c *Container, m *Mount) if mustCopyEmptyDir { // Cache the host emptyDir guestPath so other containers in the pod // share the same copied writable directory. - f.srcGuestMapLock.Lock() f.srcGuestMap[m.Source] = guestPath - f.srcGuestMapLock.Unlock() } } else { // These mounts are created in the shared dir @@ -480,7 +477,7 @@ func (f *FilesystemShare) UnshareFile(ctx context.Context, c *Container, m *Moun } } - // Not deleting from f.srcGuestMapLock since this function is not + // Not deleting from f.srcGuestMap since this function is not // called for mounts without HostPath. return nil diff --git a/src/tools/genpolicy/src/mount_and_storage.rs b/src/tools/genpolicy/src/mount_and_storage.rs index 992ed7bdbd..f144c182ce 100644 --- a/src/tools/genpolicy/src/mount_and_storage.rs +++ b/src/tools/genpolicy/src/mount_and_storage.rs @@ -113,23 +113,13 @@ pub fn get_mount_and_storage( ); if let Some(emptyDir) = &yaml_volume.emptyDir { - let settings_volumes = &settings.volumes; - 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( + get_empty_dir_mount( settings, p_mounts, storages, + emptyDir, 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"); @@ -146,7 +136,45 @@ pub fn get_mount_and_storage( } } -fn get_empty_dir_mount_and_storage( +fn get_empty_dir_mount( + settings: &settings::Settings, + p_mounts: &mut Vec, + storages: &mut Vec, + emptyDir: &volume::EmptyDirVolumeSource, + yaml_mount: &pod::VolumeMount, + pod_security_context: &Option, +) { + let settings_volumes = &settings.volumes; + 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), + }; + + if emptyDir.medium.as_deref() == Some("Memory") || block_encrypted_emptydir { + get_guest_empty_dir_mount_and_storage( + settings, + p_mounts, + storages, + yaml_mount, + volume, + pod_security_context, + block_encrypted_emptydir, + ); + } else { + let access = if yaml_mount.readOnly == Some(true) { + debug!("setting read only access for emptyDir mount"); + "ro" + } else { + "rw" + }; + get_host_empty_dir_mount(yaml_mount, p_mounts, access); + } +} + +fn get_guest_empty_dir_mount_and_storage( settings: &settings::Settings, p_mounts: &mut Vec, storages: &mut Vec, @@ -172,7 +200,7 @@ fn get_empty_dir_mount_and_storage( Some(gid) if gid > 0 => protobuf::MessageField::some(agent::FSGroup { group_id: u32::try_from(gid).unwrap_or_else(|_| { panic!( - "get_empty_dir_mount_and_storage: securityContext.fsGroup {gid} \ + "get_guest_empty_dir_mount_and_storage: securityContext.fsGroup {gid} \ must be <= {}", u32::MAX ) @@ -347,14 +375,43 @@ fn get_shared_bind_mount( propagation: &str, access: &str, ) { - // The Kata Shim filepath.Base() to extract the last element of this path, in - // https://github.com/kata-containers/kata-containers/blob/5e46f814dd79ab6b34588a83825260413839735a/src/runtime/virtcontainers/fs_share_linux.go#L305 - // In Rust, Path::file_name() has a similar behavior. - let path = Path::new(&yaml_mount.mountPath); - let mount_path = path.file_name().unwrap().to_str().unwrap(); - + let mount_path = Path::new(&yaml_mount.mountPath) + .file_name() + .unwrap() + .to_str() + .unwrap(); + let mount_path = regex::escape(mount_path); let source = format!("$(sfprefix){mount_path}$"); + add_shared_bind_mount(yaml_mount, p_mounts, source, propagation, access); +} + +fn get_host_empty_dir_mount( + yaml_mount: &pod::VolumeMount, + p_mounts: &mut Vec, + access: &str, +) { + let name = regex::escape(&yaml_mount.name); + let source = format!("^$(cpath)/sandbox-[0-9a-f]{{16}}-{name}$"); + push_shared_bind_mount(yaml_mount, p_mounts, source, "rprivate", access); + + let mount_path = Path::new(&yaml_mount.mountPath) + .file_name() + .unwrap() + .to_str() + .unwrap(); + let mount_path = regex::escape(mount_path); + let source = format!("$(sfprefix){mount_path}$"); + push_shared_bind_mount(yaml_mount, p_mounts, source, "rprivate", access); +} + +fn add_shared_bind_mount( + yaml_mount: &pod::VolumeMount, + p_mounts: &mut Vec, + source: String, + propagation: &str, + access: &str, +) { let dest = yaml_mount.mountPath.clone(); let type_ = "bind".to_string(); let options = vec![ @@ -369,16 +426,31 @@ fn get_shared_bind_mount( policy_mount.source = source; policy_mount.options = options; } else { - debug!("get_shared_bind_mount: adding dest = {dest}, source = {source}"); - p_mounts.push(policy::KataMount { - destination: dest, - type_, - source, - options, - }); + push_shared_bind_mount(yaml_mount, p_mounts, source, propagation, access); } } +fn push_shared_bind_mount( + yaml_mount: &pod::VolumeMount, + p_mounts: &mut Vec, + source: String, + propagation: &str, + access: &str, +) { + let dest = yaml_mount.mountPath.clone(); + debug!("get_shared_bind_mount: adding dest = {dest}, source = {source}"); + p_mounts.push(policy::KataMount { + destination: dest, + type_: "bind".to_string(), + source, + options: vec![ + "rbind".to_string(), + propagation.to_string(), + access.to_string(), + ], + }); +} + fn get_downward_api_mount(yaml_mount: &pod::VolumeMount, p_mounts: &mut Vec) { let mount_path = if let Some(byte_index) = str::rfind(&yaml_mount.mountPath, '/') { str::from_utf8(&yaml_mount.mountPath.as_bytes()[byte_index + 1..]).unwrap()