Skip to content

Commit

Permalink
Integration test for capabilities
Browse files Browse the repository at this point in the history
Verify non-root containers are able to use file
capabilities.

Signed-off-by: Luboslav Pivarc <lpivarc@redhat.com>
Co-authored-by: Cory Snider <csnider@mirantis.com>
Signed-off-by: Cory Snider <csnider@mirantis.com>
  • Loading branch information
xpivarc and corhere committed Jul 24, 2023
1 parent 3aef732 commit 42fa7a1
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 0 deletions.
108 changes: 108 additions & 0 deletions integration/capabilities/capabilities_linux_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package capabilities

import (
"bytes"
"context"
"io"
"strings"
"testing"
"time"

"github.com/docker/docker/api/types"
"github.com/docker/docker/integration/internal/container"
"github.com/docker/docker/pkg/stdcopy"
"github.com/docker/docker/testutil/fakecontext"

"gotest.tools/v3/assert"
"gotest.tools/v3/poll"
)

func TestNoNewPrivileges(t *testing.T) {
defer setupTest(t)()

withFileCapability := `
FROM debian:bullseye-slim
RUN apt-get update && apt-get install -y libcap2-bin --no-install-recommends
RUN setcap CAP_DAC_OVERRIDE=+eip /bin/cat
RUN echo "hello" > /txt && chown 0:0 /txt && chmod 700 /txt
RUN useradd -u 1500 test
`
imageTag := "captest"

source := fakecontext.New(t, "", fakecontext.WithDockerfile(withFileCapability))
defer source.Close()

client := testEnv.APIClient()

// Build image
ctx := context.TODO()
resp, err := client.ImageBuild(ctx,
source.AsTarReader(t),
types.ImageBuildOptions{
Tags: []string{imageTag},
})
assert.NilError(t, err)
_, err = io.Copy(io.Discard, resp.Body)
assert.NilError(t, err)
resp.Body.Close()

testCases := []struct {
doc string
opts []func(*container.TestContainerConfig)
stdOut, stdErr string
}{
{
doc: "CapabilityRequested=true",
opts: []func(*container.TestContainerConfig){
container.WithUser("test"),
container.WithCapability("CAP_DAC_OVERRIDE"),
},
stdOut: "hello",
},
{
doc: "CapabilityRequested=false",
opts: []func(*container.TestContainerConfig){
container.WithUser("test"),
container.WithDropCapability("CAP_DAC_OVERRIDE"),
},
stdErr: "exec /bin/cat: operation not permitted",
},
}

for _, tc := range testCases {
tc := tc
t.Run(tc.doc, func(t *testing.T) {
// Run the container with the image
opts := append(tc.opts,
container.WithImage(imageTag),
container.WithCmd("/bin/cat", "/txt"),
container.WithSecurityOpt("no-new-privileges=true"),
)
cid := container.Run(ctx, t, client, opts...)
poll.WaitOn(t, container.IsInState(ctx, client, cid, "exited"), poll.WithDelay(100*time.Millisecond))

// Assert on outputs
logReader, err := client.ContainerLogs(ctx, cid, types.ContainerLogsOptions{
ShowStdout: true,
ShowStderr: true,
})
assert.NilError(t, err)
defer logReader.Close()

var actualStdout, actualStderr bytes.Buffer
_, err = stdcopy.StdCopy(&actualStdout, &actualStderr, logReader)
assert.NilError(t, err)

stdOut := strings.TrimSpace(actualStdout.String())
stdErr := strings.TrimSpace(actualStderr.String())
if stdOut != tc.stdOut {
t.Fatalf("test produced invalid output: %q, expected %q. Stderr:%q", stdOut, tc.stdOut, stdErr)
}
if stdErr != tc.stdErr {
t.Fatalf("test produced invalid error: %q, expected %q. Stdout:%q", stdErr, tc.stdErr, stdOut)

}
})
}

}
33 changes: 33 additions & 0 deletions integration/capabilities/main_linux_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package capabilities

import (
"fmt"
"os"
"testing"

"github.com/docker/docker/testutil/environment"
)

var testEnv *environment.Execution

func TestMain(m *testing.M) {
var err error
testEnv, err = environment.New()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
err = environment.EnsureFrozenImagesLinux(testEnv)
if err != nil {
fmt.Println(err)
os.Exit(1)
}

testEnv.Print()
os.Exit(m.Run())
}

func setupTest(t *testing.T) func() {
environment.ProtectAll(t, testEnv)
return func() { testEnv.Clean(t) }
}
18 changes: 18 additions & 0 deletions integration/internal/container/ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,21 @@ func WithCDIDevices(cdiDeviceNames ...string) func(*TestContainerConfig) {
c.HostConfig.DeviceRequests = append(c.HostConfig.DeviceRequests, request)
}
}

func WithCapability(capabilities ...string) func(*TestContainerConfig) {
return func(c *TestContainerConfig) {
c.HostConfig.CapAdd = append(c.HostConfig.CapAdd, capabilities...)
}
}

func WithDropCapability(capabilities ...string) func(*TestContainerConfig) {
return func(c *TestContainerConfig) {
c.HostConfig.CapDrop = append(c.HostConfig.CapDrop, capabilities...)
}
}

func WithSecurityOpt(opt string) func(*TestContainerConfig) {
return func(c *TestContainerConfig) {
c.HostConfig.SecurityOpt = append(c.HostConfig.SecurityOpt, opt)
}
}

0 comments on commit 42fa7a1

Please sign in to comment.