Files
moby/integration/capabilities/capabilities_linux_test.go
Sebastiaan van Stijn d3e45f8743 testutil: move back to internal
This package was originally internal, but was moved out when BuildKit
used it for its integration tests. That's no longer the case, so we
can make it internal again.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-08 10:08:30 +02:00

104 lines
2.9 KiB
Go

package capabilities
import (
"bytes"
"io"
"strings"
"testing"
"github.com/moby/moby/api/pkg/stdcopy"
containertypes "github.com/moby/moby/api/types/container"
"github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/container"
"github.com/moby/moby/v2/internal/testutil"
"github.com/moby/moby/v2/internal/testutil/fakecontext"
"gotest.tools/v3/assert"
"gotest.tools/v3/poll"
)
func TestNoNewPrivileges(t *testing.T) {
ctx := 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()
apiClient := testEnv.APIClient()
// Build image
resp, err := apiClient.ImageBuild(ctx, source.AsTarReader(t), client.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 {
t.Run(tc.doc, func(t *testing.T) {
ctx := testutil.StartSpan(ctx, 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, apiClient, opts...)
poll.WaitOn(t, container.IsInState(ctx, apiClient, cid, containertypes.StateExited))
// Assert on outputs
logReader, err := apiClient.ContainerLogs(ctx, cid, client.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)
}
})
}
}