Fix the Inheritable capability defaults.

The Linux kernel never sets the Inheritable capability flag to
anything other than empty. Non-empty values are always exclusively
set by userspace code.

[The kernel stopped defaulting this set of capability values to the
 full set in 2000 after a privilege escalation with Capabilities
 affecting Sendmail and others.]

Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
This commit is contained in:
Andrew G. Morgan 2021-09-08 12:57:23 -07:00 committed by Samuel Karp
parent 52b8ca5545
commit 6906b57c72
No known key found for this signature in database
GPG Key ID: 7F8CDFDD70CC3D44
5 changed files with 7 additions and 17 deletions

View File

@ -148,10 +148,9 @@ func populateDefaultUnixSpec(ctx context.Context, s *Spec, id string) error {
GID: 0,
},
Capabilities: &specs.LinuxCapabilities{
Bounding: defaultUnixCaps(),
Permitted: defaultUnixCaps(),
Inheritable: defaultUnixCaps(),
Effective: defaultUnixCaps(),
Bounding: defaultUnixCaps(),
Permitted: defaultUnixCaps(),
Effective: defaultUnixCaps(),
},
Rlimits: []specs.POSIXRlimit{
{

View File

@ -810,7 +810,6 @@ func WithCapabilities(caps []string) SpecOpts {
s.Process.Capabilities.Bounding = caps
s.Process.Capabilities.Effective = caps
s.Process.Capabilities.Permitted = caps
s.Process.Capabilities.Inheritable = caps
return nil
}
@ -845,7 +844,6 @@ func WithAddedCapabilities(caps []string) SpecOpts {
&s.Process.Capabilities.Bounding,
&s.Process.Capabilities.Effective,
&s.Process.Capabilities.Permitted,
&s.Process.Capabilities.Inheritable,
} {
if !capsContain(*cl, c) {
*cl = append(*cl, c)
@ -865,7 +863,6 @@ func WithDroppedCapabilities(caps []string) SpecOpts {
&s.Process.Capabilities.Bounding,
&s.Process.Capabilities.Effective,
&s.Process.Capabilities.Permitted,
&s.Process.Capabilities.Inheritable,
} {
removeCap(cl, c)
}
@ -880,7 +877,7 @@ func WithDroppedCapabilities(caps []string) SpecOpts {
func WithAmbientCapabilities(caps []string) SpecOpts {
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
setCapabilities(s)
s.Process.Capabilities.Inheritable = caps
s.Process.Capabilities.Ambient = caps
return nil
}

View File

@ -39,7 +39,6 @@ func TestAddCaps(t *testing.T) {
s.Process.Capabilities.Bounding,
s.Process.Capabilities.Effective,
s.Process.Capabilities.Permitted,
s.Process.Capabilities.Inheritable,
} {
if !capsContain(cl, "CAP_CHOWN") {
t.Errorf("cap list %d does not contain added cap", i)
@ -63,7 +62,6 @@ func TestDropCaps(t *testing.T) {
s.Process.Capabilities.Bounding,
s.Process.Capabilities.Effective,
s.Process.Capabilities.Permitted,
s.Process.Capabilities.Inheritable,
} {
if capsContain(cl, "CAP_CHOWN") {
t.Errorf("cap list %d contains dropped cap", i)
@ -82,7 +80,6 @@ func TestDropCaps(t *testing.T) {
s.Process.Capabilities.Bounding,
s.Process.Capabilities.Effective,
s.Process.Capabilities.Permitted,
s.Process.Capabilities.Inheritable,
} {
if capsContain(cl, "CAP_FOWNER") {
t.Errorf("cap list %d contains dropped cap", i)
@ -103,7 +100,6 @@ func TestDropCaps(t *testing.T) {
s.Process.Capabilities.Bounding,
s.Process.Capabilities.Effective,
s.Process.Capabilities.Permitted,
s.Process.Capabilities.Inheritable,
} {
if len(cl) != 0 {
t.Errorf("cap list %d is not empty", i)

View File

@ -45,7 +45,6 @@ func TestGenerateSpec(t *testing.T) {
for _, cl := range [][]string{
s.Process.Capabilities.Bounding,
s.Process.Capabilities.Permitted,
s.Process.Capabilities.Inheritable,
s.Process.Capabilities.Effective,
} {
for i := 0; i < len(defaults); i++ {
@ -193,8 +192,8 @@ func TestWithCapabilities(t *testing.T) {
if len(s.Process.Capabilities.Permitted) != 1 || s.Process.Capabilities.Permitted[0] != "CAP_SYS_ADMIN" {
t.Error("Unexpected capabilities set")
}
if len(s.Process.Capabilities.Inheritable) != 1 || s.Process.Capabilities.Inheritable[0] != "CAP_SYS_ADMIN" {
t.Error("Unexpected capabilities set")
if len(s.Process.Capabilities.Inheritable) != 0 {
t.Errorf("Unexpected capabilities set: length is non zero (%d)", len(s.Process.Capabilities.Inheritable))
}
}

View File

@ -255,15 +255,14 @@ func TestContainerCapabilities(t *testing.T) {
for _, include := range test.includes {
assert.Contains(t, spec.Process.Capabilities.Bounding, include)
assert.Contains(t, spec.Process.Capabilities.Effective, include)
assert.Contains(t, spec.Process.Capabilities.Inheritable, include)
assert.Contains(t, spec.Process.Capabilities.Permitted, include)
}
for _, exclude := range test.excludes {
assert.NotContains(t, spec.Process.Capabilities.Bounding, exclude)
assert.NotContains(t, spec.Process.Capabilities.Effective, exclude)
assert.NotContains(t, spec.Process.Capabilities.Inheritable, exclude)
assert.NotContains(t, spec.Process.Capabilities.Permitted, exclude)
}
assert.Empty(t, spec.Process.Capabilities.Inheritable)
assert.Empty(t, spec.Process.Capabilities.Ambient)
}
}