Improper Preservation of Permissions in containerd
Description
containerd is an open source container runtime. On installations using SELinux, such as EL8 (CentOS, RHEL), Fedora, or SUSE MicroOS, with containerd since v1.5.0-beta.0 as the backing container runtime interface (CRI), an unprivileged pod scheduled to the node may bind mount, via hostPath volume, any privileged, regular file on disk for complete read/write access (sans delete). Such is achieved by placing the in-container location of the hostPath volume mount at either /etc/hosts, /etc/hostname, or /etc/resolv.conf. These locations are being relabeled indiscriminately to match the container process-label which effectively elevates permissions for savvy containers that would not normally be able to access privileged host files. This issue has been resolved in version 1.5.9. Users are advised to upgrade as soon as possible.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/containerd/containerdGo | >= 1.5.0, < 1.5.9 | 1.5.9 |
Affected products
1- Range: >= 1.5.0, < 1.5.9
Patches
2f7f08f0e34fbRevert "[cri] label etc files for selinux containers"
2 files changed · +1 −25
pkg/cri/opts/spec_linux.go+0 −24 modified@@ -225,30 +225,6 @@ func WithMounts(osi osinterface.OS, config *runtime.ContainerConfig, extra []*ru } } -const ( - etcHosts = "/etc/hosts" - etcHostname = "/etc/hostname" - resolvConfPath = "/etc/resolv.conf" -) - -// WithRelabeledContainerMounts relabels the default container mounts for files in /etc -func WithRelabeledContainerMounts(mountLabel string) oci.SpecOpts { - return func(ctx context.Context, client oci.Client, _ *containers.Container, s *runtimespec.Spec) (err error) { - if mountLabel == "" { - return nil - } - for _, m := range s.Mounts { - switch m.Destination { - case etcHosts, etcHostname, resolvConfPath: - if err := label.Relabel(m.Source, mountLabel, false); err != nil { - return err - } - } - } - return nil - } -} - // Ensure mount point on which path is mounted, is shared. func ensureShared(path string, lookupMount func(string) (mount.Info, error)) error { mountInfo, err := lookupMount(path)
pkg/cri/server/container_create_linux.go+1 −1 modified@@ -192,7 +192,7 @@ func (c *criService) containerSpec( } }() - specOpts = append(specOpts, customopts.WithMounts(c.os, config, extraMounts, mountLabel), customopts.WithRelabeledContainerMounts(mountLabel)) + specOpts = append(specOpts, customopts.WithMounts(c.os, config, extraMounts, mountLabel)) if !c.config.DisableProcMount { // Change the default masked/readonly paths to empty slices
a731039238c6[cri] label etc files for selinux containers
2 files changed · +25 −1
pkg/cri/opts/spec_linux.go+24 −0 modified@@ -242,6 +242,30 @@ func WithMounts(osi osinterface.OS, config *runtime.ContainerConfig, extra []*ru } } +const ( + etcHosts = "/etc/hosts" + etcHostname = "/etc/hostname" + resolvConfPath = "/etc/resolv.conf" +) + +// WithRelabeledContainerMounts relabels the default container mounts for files in /etc +func WithRelabeledContainerMounts(mountLabel string) oci.SpecOpts { + return func(ctx context.Context, client oci.Client, _ *containers.Container, s *runtimespec.Spec) (err error) { + if mountLabel == "" { + return nil + } + for _, m := range s.Mounts { + switch m.Destination { + case etcHosts, etcHostname, resolvConfPath: + if err := label.Relabel(m.Source, mountLabel, false); err != nil { + return err + } + } + } + return nil + } +} + // Ensure mount point on which path is mounted, is shared. func ensureShared(path string, lookupMount func(string) (mount.Info, error)) error { mountInfo, err := lookupMount(path)
pkg/cri/server/container_create_linux.go+1 −1 modified@@ -183,7 +183,7 @@ func (c *criService) containerSpec(id string, sandboxID string, sandboxPid uint3 } }() - specOpts = append(specOpts, customopts.WithMounts(c.os, config, extraMounts, mountLabel)) + specOpts = append(specOpts, customopts.WithMounts(c.os, config, extraMounts, mountLabel), customopts.WithRelabeledContainerMounts(mountLabel)) if !c.config.DisableProcMount { // Apply masked paths if specified.
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
10- github.com/advisories/GHSA-mvff-h3cj-wj9cghsaADVISORY
- lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/GD5GH7NMK5VJMA2Y5CYB5O5GTPYMWMLX/mitrevendor-advisoryx_refsource_FEDORA
- lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/MPDIZMI7ZPERSZE2XO265UCK5IWM7CID/mitrevendor-advisoryx_refsource_FEDORA
- nvd.nist.gov/vuln/detail/CVE-2021-43816ghsaADVISORY
- github.com/containerd/containerd/commit/a731039238c62be081eb8c31525b988415745eeaghsax_refsource_MISCWEB
- github.com/containerd/containerd/issues/6194ghsax_refsource_MISCWEB
- github.com/containerd/containerd/security/advisories/GHSA-mvff-h3cj-wj9cghsax_refsource_CONFIRMWEB
- github.com/dweomer/containerd/commit/f7f08f0e34fb97392b0d382e58916d6865100299ghsax_refsource_MISCWEB
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/GD5GH7NMK5VJMA2Y5CYB5O5GTPYMWMLXghsaWEB
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/MPDIZMI7ZPERSZE2XO265UCK5IWM7CIDghsaWEB
News mentions
0No linked articles in our index yet.