github.com/rish1988/moby@v25.0.2+incompatible/integration/capabilities/capabilities_linux_test.go (about) 1 package capabilities 2 3 import ( 4 "bytes" 5 "io" 6 "strings" 7 "testing" 8 "time" 9 10 "github.com/docker/docker/api/types" 11 containertypes "github.com/docker/docker/api/types/container" 12 "github.com/docker/docker/integration/internal/container" 13 "github.com/docker/docker/pkg/stdcopy" 14 "github.com/docker/docker/testutil" 15 "github.com/docker/docker/testutil/fakecontext" 16 17 "gotest.tools/v3/assert" 18 "gotest.tools/v3/poll" 19 ) 20 21 func TestNoNewPrivileges(t *testing.T) { 22 ctx := setupTest(t) 23 24 withFileCapability := ` 25 FROM debian:bullseye-slim 26 RUN apt-get update && apt-get install -y libcap2-bin --no-install-recommends 27 RUN setcap CAP_DAC_OVERRIDE=+eip /bin/cat 28 RUN echo "hello" > /txt && chown 0:0 /txt && chmod 700 /txt 29 RUN useradd -u 1500 test 30 ` 31 imageTag := "captest" 32 33 source := fakecontext.New(t, "", fakecontext.WithDockerfile(withFileCapability)) 34 defer source.Close() 35 36 client := testEnv.APIClient() 37 38 // Build image 39 resp, err := client.ImageBuild(ctx, 40 source.AsTarReader(t), 41 types.ImageBuildOptions{ 42 Tags: []string{imageTag}, 43 }) 44 assert.NilError(t, err) 45 _, err = io.Copy(io.Discard, resp.Body) 46 assert.NilError(t, err) 47 resp.Body.Close() 48 49 testCases := []struct { 50 doc string 51 opts []func(*container.TestContainerConfig) 52 stdOut, stdErr string 53 }{ 54 { 55 doc: "CapabilityRequested=true", 56 opts: []func(*container.TestContainerConfig){ 57 container.WithUser("test"), 58 container.WithCapability("CAP_DAC_OVERRIDE"), 59 }, 60 stdOut: "hello", 61 }, 62 { 63 doc: "CapabilityRequested=false", 64 opts: []func(*container.TestContainerConfig){ 65 container.WithUser("test"), 66 container.WithDropCapability("CAP_DAC_OVERRIDE"), 67 }, 68 stdErr: "exec /bin/cat: operation not permitted", 69 }, 70 } 71 72 for _, tc := range testCases { 73 tc := tc 74 t.Run(tc.doc, func(t *testing.T) { 75 ctx := testutil.StartSpan(ctx, t) 76 77 // Run the container with the image 78 opts := append(tc.opts, 79 container.WithImage(imageTag), 80 container.WithCmd("/bin/cat", "/txt"), 81 container.WithSecurityOpt("no-new-privileges=true"), 82 ) 83 cid := container.Run(ctx, t, client, opts...) 84 poll.WaitOn(t, container.IsInState(ctx, client, cid, "exited"), poll.WithDelay(100*time.Millisecond)) 85 86 // Assert on outputs 87 logReader, err := client.ContainerLogs(ctx, cid, containertypes.LogsOptions{ 88 ShowStdout: true, 89 ShowStderr: true, 90 }) 91 assert.NilError(t, err) 92 defer logReader.Close() 93 94 var actualStdout, actualStderr bytes.Buffer 95 _, err = stdcopy.StdCopy(&actualStdout, &actualStderr, logReader) 96 assert.NilError(t, err) 97 98 stdOut := strings.TrimSpace(actualStdout.String()) 99 stdErr := strings.TrimSpace(actualStderr.String()) 100 if stdOut != tc.stdOut { 101 t.Fatalf("test produced invalid output: %q, expected %q. Stderr:%q", stdOut, tc.stdOut, stdErr) 102 } 103 if stdErr != tc.stdErr { 104 t.Fatalf("test produced invalid error: %q, expected %q. Stdout:%q", stdErr, tc.stdErr, stdOut) 105 } 106 }) 107 } 108 }