Skip to content

[Linux] Managed cgroup v2 memory limit traversal can escape the hierarchy mount root #133470

Description

@cuishuang

Description

The managed cgroup v2 memory limit traversal in src/libraries/Common/src/Interop/Linux/cgroups/Interop.cgroups.cs can walk above the cgroup hierarchy mount root.

FindCGroupPath can legitimately return the hierarchy mount itself when the current process is assigned to the visible cgroup hierarchy root. For example:

hierarchyRoot = /some/container
hierarchyMount = /sys/fs/cgroup
cgroupPathRelativeToMount = /some/container

This produces:

/sys/fs/cgroup

TryGetMemoryLimitV2 currently uses a do/while loop that moves to the parent directory before checking whether the mount root has been reached. When the current path is already equal to the mount path, the traversal therefore continues above the cgroup hierarchy and can eventually dereference a null path.

The CoreCLR C++ implementation already protects this boundary (PR #130377), but the managed Common implementation does not.

Reproduction Steps

  1. Run on Linux with cgroup v2 enabled.
  2. Place the current process at the cgroup hierarchy mount root.
  3. Call Interop.cgroups.TryGetMemoryLimit.
  4. Observe that the managed traversal attempts to walk above the mount root and can fail while resolving the parent path.

Expected behavior

When the current cgroup path equals the hierarchy mount path, traversal should stop at that path and must not inspect any parent directory.

Actual behavior

The loop executes its body and calls Path.GetDirectoryName even when the current path is already the hierarchy mount root. The traversal can continue through parent directories and eventually reach a null path.

Regression?

The issue appears to be a latent edge case in the managed cgroup v2 implementation. The corresponding CoreCLR native implementation was already fixed in #130377.

Known Workarounds

No reliable application-level workaround. The fallback to procfs is not reached if the traversal throws before returning from TryGetMemoryLimit.

Configuration

  • OS: Linux
  • cgroup version: v2
  • Affected code: managed Common cgroup interop
  • Relevant environments: containers and cgroup namespaces whose visible root is the current process cgroup

Other information

The proposed fix changes the loop so that it only reads and moves upward while the current path is below the hierarchy mount root. It also adds tests for the equality case and for nested paths that must stop at the mount root.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions