libct: enforce strict tmpfs limits for masked paths

Previously, masked directories (e.g., /proc/acpi, /proc/scsi) were
mounted as read-only tmpfs without explicit size or inode limits.
Although these mounts are meant to be empty and unwritable, the lack
of resource constraints means that—should an attacker bypass the
read-only protection (e.g., via container escape, mount namespace
manipulation, or a kernel vulnerability)—the tmpfs could consume up
to 50% of system memory by default (the kernel's default tmpfs limit).

To mitigate this risk in high-density container environments and
adhere to the principle of least privilege, we now explicitly set:
  - nr_blocks=1 (sufficient for at most one block size)
  - nr_inodes=1 (sufficient for at most one inode)
Ref: https://man7.org/linux/man-pages/man5/tmpfs.5.html

These limits ensure that even if compromised, kernel memory usage
remains strictly bounded and negligible.

This change aligns with best practices used by other container
runtimes and strengthens defense-in-depth for sensitive masked paths.

Co-authored-by: Davanum Srinivas <davanum@gmail.com>
Refactored-by: lifubang <lifubang@acmcoder.com>
Signed-off-by: lifubang <lifubang@acmcoder.com>
(cherry picked from commit e57a7a4c8f)
Signed-off-by: lifubang <lifubang@acmcoder.com>
This commit is contained in:
lifubang
2026-05-12 08:54:29 +00:00
parent 0fc2921263
commit 24867ade0a
+1 -1
View File
@@ -1365,7 +1365,7 @@ func maskPaths(paths []string, mountLabel string) error {
if st.IsDir() {
// Destination is a directory: bind mount a ro tmpfs over it.
dstType = "dir"
err = mount("tmpfs", path, "tmpfs", unix.MS_RDONLY, label.FormatMountLabel("", mountLabel))
err = mount("tmpfs", path, "tmpfs", unix.MS_RDONLY, label.FormatMountLabel("nr_blocks=1,nr_inodes=1", mountLabel))
} else {
// Destination is a file: mount it to /dev/null.
dstType = "path"