rootless: support --pid=host

Fix #41457

related: https://github.com/containers/podman/blob/v3.0.0-rc1/pkg/specgen/generate/oci.go#L248-L257

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
Akihiro Suda 2021-01-19 14:12:43 +09:00
parent 7994443c15
commit 227687f2ef
No known key found for this signature in database
GPG Key ID: 49524C6F9F638F1A
2 changed files with 61 additions and 1 deletions

View File

@ -15,7 +15,6 @@ import (
func TestPidHost(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
skip.If(t, testEnv.IsRemoteDaemon())
skip.If(t, testEnv.IsRootless, "https://github.com/moby/moby/issues/41457")
hostPid, err := os.Readlink("/proc/1/ns/pid")
assert.NilError(t, err)

View File

@ -2,7 +2,10 @@ package specconv // import "github.com/docker/docker/rootless/specconv"
import (
"io/ioutil"
"os"
"path"
"strconv"
"strings"
specs "github.com/opencontainers/runtime-spec/specs-go"
)
@ -10,6 +13,7 @@ import (
// ToRootless converts spec to be compatible with "rootless" runc.
// * Remove non-supported cgroups
// * Fix up OOMScoreAdj
// * Fix up /proc if --pid=host
//
// v2Controllers should be non-nil only if running with v2 and systemd.
func ToRootless(spec *specs.Spec, v2Controllers []string) error {
@ -70,5 +74,62 @@ func toRootless(spec *specs.Spec, v2Controllers []string, currentOOMScoreAdj int
if spec.Process.OOMScoreAdj != nil && *spec.Process.OOMScoreAdj < currentOOMScoreAdj {
*spec.Process.OOMScoreAdj = currentOOMScoreAdj
}
// Fix up /proc if --pid=host
pidHost, err := isPidHost(spec)
if err != nil {
return err
}
if !pidHost {
return nil
}
return bindMountHostProcfs(spec)
}
func isPidHost(spec *specs.Spec) (bool, error) {
for _, ns := range spec.Linux.Namespaces {
if ns.Type == specs.PIDNamespace {
if ns.Path == "" {
return false, nil
}
pidNS, err := os.Readlink(ns.Path)
if err != nil {
return false, err
}
selfPidNS, err := os.Readlink("/proc/self/ns/pid")
if err != nil {
return false, err
}
return pidNS == selfPidNS, nil
}
}
return true, nil
}
func bindMountHostProcfs(spec *specs.Spec) error {
// Replace procfs mount with rbind
// https://github.com/containers/podman/blob/v3.0.0-rc1/pkg/specgen/generate/oci.go#L248-L257
for i, m := range spec.Mounts {
if path.Clean(m.Destination) == "/proc" {
newM := specs.Mount{
Destination: "/proc",
Type: "bind",
Source: "/proc",
Options: []string{"rbind", "nosuid", "noexec", "nodev"},
}
spec.Mounts[i] = newM
}
}
// Remove ReadonlyPaths for /proc/*
newROP := spec.Linux.ReadonlyPaths[:0]
for _, s := range spec.Linux.ReadonlyPaths {
s = path.Clean(s)
if !strings.HasPrefix(s, "/proc/") {
newROP = append(newROP, s)
}
}
spec.Linux.ReadonlyPaths = newROP
return nil
}