Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[20.10 backport] daemon.WithCommonOptions() fix detection of user-namespaces #43084

Merged
merged 1 commit into from Jan 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion daemon/oci_linux.go
Expand Up @@ -767,7 +767,8 @@ func WithCommonOptions(daemon *Daemon, c *container.Container) coci.SpecOpts {
// joining an existing namespace, only if we create a new net namespace.
if c.HostConfig.NetworkMode.IsPrivate() {
// We cannot set up ping socket support in a user namespace
if !c.HostConfig.UsernsMode.IsPrivate() && sysctlExists("net.ipv4.ping_group_range") {
userNS := daemon.configStore.RemappedRoot != "" && c.HostConfig.UsernsMode.IsPrivate()
if !userNS && !sys.RunningInUserNS() && sysctlExists("net.ipv4.ping_group_range") {
// allow unprivileged ICMP echo sockets without CAP_NET_RAW
s.Linux.Sysctl["net.ipv4.ping_group_range"] = "0 2147483647"
}
Expand Down
16 changes: 14 additions & 2 deletions daemon/oci_linux_test.go
Expand Up @@ -120,7 +120,6 @@ func TestSysctlOverride(t *testing.T) {
HostConfig: &containertypes.HostConfig{
NetworkMode: "bridge",
Sysctls: map[string]string{},
UsernsMode: "host",
},
}
d := setupFakeDaemon(t, c)
Expand Down Expand Up @@ -148,6 +147,20 @@ func TestSysctlOverride(t *testing.T) {
assert.Equal(t, s.Hostname, "foobar")
assert.Equal(t, s.Linux.Sysctl["kernel.domainname"], c.HostConfig.Sysctls["kernel.domainname"])
assert.Equal(t, s.Linux.Sysctl["net.ipv4.ip_unprivileged_port_start"], c.HostConfig.Sysctls["net.ipv4.ip_unprivileged_port_start"])

// Ensure the ping_group_range is not set on a daemon with user-namespaces enabled
d.configStore.RemappedRoot = "dummy:dummy"
s, err = d.createSpec(c)
assert.NilError(t, err)
_, ok := s.Linux.Sysctl["net.ipv4.ping_group_range"]
assert.Assert(t, !ok)

// Ensure the ping_group_range is set on a container in "host" userns mode
// on a daemon with user-namespaces enabled
c.HostConfig.UsernsMode = "host"
s, err = d.createSpec(c)
assert.NilError(t, err)
assert.Equal(t, s.Linux.Sysctl["net.ipv4.ping_group_range"], "0 2147483647")
}

// TestSysctlOverrideHost ensures that any implicit network sysctls are not set
Expand All @@ -159,7 +172,6 @@ func TestSysctlOverrideHost(t *testing.T) {
HostConfig: &containertypes.HostConfig{
NetworkMode: "host",
Sysctls: map[string]string{},
UsernsMode: "host",
},
}
d := setupFakeDaemon(t, c)
Expand Down
29 changes: 29 additions & 0 deletions integration/container/run_linux_test.go
Expand Up @@ -99,3 +99,32 @@ func TestHostnameDnsResolution(t *testing.T) {
assert.Check(t, is.Equal("", res.Stderr()))
assert.Equal(t, 0, res.ExitCode)
}

func TestUnprivilegedPortsAndPing(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
skip.If(t, testEnv.IsRootless, "rootless mode doesn't support setting net.ipv4.ping_group_range and net.ipv4.ip_unprivileged_port_start")

defer setupTest(t)()
client := testEnv.APIClient()
ctx := context.Background()

cID := container.Run(ctx, t, client, func(c *container.TestContainerConfig) {
c.Config.User = "1000:1000"
})

poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond))

// Check net.ipv4.ping_group_range.
res, err := container.Exec(ctx, client, cID, []string{"cat", "/proc/sys/net/ipv4/ping_group_range"})
assert.NilError(t, err)
assert.Assert(t, is.Len(res.Stderr(), 0))
assert.Equal(t, 0, res.ExitCode)
assert.Equal(t, `0 2147483647`, strings.TrimSpace(res.Stdout()))

// Check net.ipv4.ip_unprivileged_port_start.
res, err = container.Exec(ctx, client, cID, []string{"cat", "/proc/sys/net/ipv4/ip_unprivileged_port_start"})
assert.NilError(t, err)
assert.Assert(t, is.Len(res.Stderr(), 0))
assert.Equal(t, 0, res.ExitCode)
assert.Equal(t, "0", strings.TrimSpace(res.Stdout()))
}