mirror of
https://github.com/opencontainers/runc.git
synced 2025-09-27 03:46:19 +08:00

The CAP_CHECKPOINT_RESTORE linux capability provides the ability to update /proc/sys/kernel/ns_last_pid. However, because this file is under /proc, and by default both K8s and CRI-O specify that /proc/sys should be mounted as Read-Only, by default even with the capability specified, a process will not be able to write to ns_last_pid. To get around this, a pod author can specify a volume mount and a hostpath to bind-mount /proc/sys/kernel/ns_last_pid. However, runc does not allow specifying mounts under /proc. This commit adds /proc/sys/kernel/ns_last_pid to the validProcMounts string array to enable a pod author to mount ns_last_pid as read-write. The default remains unchanged; unless explicitly requested as a volume mount, ns_last_pid will remain read-only regardless of whether or not CAP_CHECKPOINT_RESTORE is specified. Signed-off-by: Irwin D'Souza <dsouzai.gh@gmail.com>
108 lines
2.3 KiB
Go
108 lines
2.3 KiB
Go
package libcontainer
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/opencontainers/runc/libcontainer/configs"
|
|
)
|
|
|
|
func TestCheckMountDestOnProc(t *testing.T) {
|
|
dest := "/rootfs/proc/sys"
|
|
err := checkProcMount("/rootfs", dest, "")
|
|
if err == nil {
|
|
t.Fatal("destination inside proc should return an error")
|
|
}
|
|
}
|
|
|
|
func TestCheckMountDestOnProcChroot(t *testing.T) {
|
|
dest := "/rootfs/proc/"
|
|
err := checkProcMount("/rootfs", dest, "/proc")
|
|
if err != nil {
|
|
t.Fatal("destination inside proc when using chroot should not return an error")
|
|
}
|
|
}
|
|
|
|
func TestCheckMountDestInSys(t *testing.T) {
|
|
dest := "/rootfs//sys/fs/cgroup"
|
|
err := checkProcMount("/rootfs", dest, "")
|
|
if err != nil {
|
|
t.Fatal("destination inside /sys should not return an error")
|
|
}
|
|
}
|
|
|
|
func TestCheckMountDestFalsePositive(t *testing.T) {
|
|
dest := "/rootfs/sysfiles/fs/cgroup"
|
|
err := checkProcMount("/rootfs", dest, "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestCheckMountDestNsLastPid(t *testing.T) {
|
|
dest := "/rootfs/proc/sys/kernel/ns_last_pid"
|
|
err := checkProcMount("/rootfs", dest, "/proc")
|
|
if err != nil {
|
|
t.Fatal("/proc/sys/kernel/ns_last_pid should not return an error")
|
|
}
|
|
}
|
|
|
|
func TestNeedsSetupDev(t *testing.T) {
|
|
config := &configs.Config{
|
|
Mounts: []*configs.Mount{
|
|
{
|
|
Device: "bind",
|
|
Source: "/dev",
|
|
Destination: "/dev",
|
|
},
|
|
},
|
|
}
|
|
if needsSetupDev(config) {
|
|
t.Fatal("expected needsSetupDev to be false, got true")
|
|
}
|
|
}
|
|
|
|
func TestNeedsSetupDevStrangeSource(t *testing.T) {
|
|
config := &configs.Config{
|
|
Mounts: []*configs.Mount{
|
|
{
|
|
Device: "bind",
|
|
Source: "/devx",
|
|
Destination: "/dev",
|
|
},
|
|
},
|
|
}
|
|
if needsSetupDev(config) {
|
|
t.Fatal("expected needsSetupDev to be false, got true")
|
|
}
|
|
}
|
|
|
|
func TestNeedsSetupDevStrangeDest(t *testing.T) {
|
|
config := &configs.Config{
|
|
Mounts: []*configs.Mount{
|
|
{
|
|
Device: "bind",
|
|
Source: "/dev",
|
|
Destination: "/devx",
|
|
},
|
|
},
|
|
}
|
|
if !needsSetupDev(config) {
|
|
t.Fatal("expected needsSetupDev to be true, got false")
|
|
}
|
|
}
|
|
|
|
func TestNeedsSetupDevStrangeSourceDest(t *testing.T) {
|
|
config := &configs.Config{
|
|
Mounts: []*configs.Mount{
|
|
{
|
|
Device: "bind",
|
|
Source: "/devx",
|
|
Destination: "/devx",
|
|
},
|
|
},
|
|
}
|
|
if !needsSetupDev(config) {
|
|
t.Fatal("expected needsSetupDev to be true, got false")
|
|
}
|
|
}
|