github.com/pwn-term/docker@v0.0.0-20210616085119-6e977cce2565/moby/integration/build/build_userns_linux_test.go (about) 1 package build // import "github.com/docker/docker/integration/build" 2 3 import ( 4 "bufio" 5 "bytes" 6 "context" 7 "io" 8 "io/ioutil" 9 "os" 10 "strings" 11 "testing" 12 13 "github.com/docker/docker/api/types" 14 "github.com/docker/docker/integration/internal/container" 15 "github.com/docker/docker/pkg/stdcopy" 16 "github.com/docker/docker/testutil/daemon" 17 "github.com/docker/docker/testutil/fakecontext" 18 "gotest.tools/v3/assert" 19 "gotest.tools/v3/skip" 20 ) 21 22 // Implements a test for https://github.com/moby/moby/issues/41723 23 // Images built in a user-namespaced daemon should have capabilities serialised in 24 // VFS_CAP_REVISION_2 (no user-namespace root uid) format rather than V3 (that includes 25 // the root uid). 26 func TestBuildUserNamespaceValidateCapabilitiesAreV2(t *testing.T) { 27 skip.If(t, testEnv.DaemonInfo.OSType != "linux") 28 skip.If(t, testEnv.IsRemoteDaemon()) 29 skip.If(t, !testEnv.IsUserNamespaceInKernel()) 30 skip.If(t, testEnv.IsRootless()) 31 32 const imageTag = "capabilities:1.0" 33 34 tmp, err := ioutil.TempDir("", "integration-") 35 assert.NilError(t, err) 36 defer os.RemoveAll(tmp) 37 38 dUserRemap := daemon.New(t) 39 dUserRemap.StartWithBusybox(t, "--userns-remap", "default") 40 dUserRemapRunning := true 41 defer func() { 42 if dUserRemapRunning { 43 dUserRemap.Stop(t) 44 } 45 }() 46 47 dockerfile := ` 48 FROM debian:bullseye 49 RUN setcap CAP_NET_BIND_SERVICE=+eip /bin/sleep 50 ` 51 52 ctx := context.Background() 53 source := fakecontext.New(t, "", fakecontext.WithDockerfile(dockerfile)) 54 defer source.Close() 55 56 clientUserRemap := dUserRemap.NewClientT(t) 57 resp, err := clientUserRemap.ImageBuild(ctx, 58 source.AsTarReader(t), 59 types.ImageBuildOptions{ 60 Tags: []string{imageTag}, 61 }) 62 assert.NilError(t, err) 63 defer resp.Body.Close() 64 buf := make([]byte, 1024) 65 for { 66 n, err := resp.Body.Read(buf) 67 if err != nil && err != io.EOF { 68 t.Fatalf("Error reading ImageBuild response: %v", err) 69 break 70 } 71 if n == 0 { 72 break 73 } 74 } 75 76 reader, err := clientUserRemap.ImageSave(ctx, []string{imageTag}) 77 assert.NilError(t, err, "failed to download capabilities image") 78 defer reader.Close() 79 80 tar, err := os.Create(tmp + "/image.tar") 81 assert.NilError(t, err, "failed to create image tar file") 82 defer tar.Close() 83 84 _, err = io.Copy(tar, reader) 85 assert.NilError(t, err, "failed to write image tar file") 86 87 dUserRemap.Stop(t) 88 dUserRemap.Cleanup(t) 89 dUserRemapRunning = false 90 91 dNoUserRemap := daemon.New(t) 92 dNoUserRemap.StartWithBusybox(t) 93 defer dNoUserRemap.Stop(t) 94 95 clientNoUserRemap := dNoUserRemap.NewClientT(t) 96 97 tarFile, err := os.Open(tmp + "/image.tar") 98 assert.NilError(t, err, "failed to open image tar file") 99 100 tarReader := bufio.NewReader(tarFile) 101 loadResp, err := clientNoUserRemap.ImageLoad(ctx, tarReader, false) 102 assert.NilError(t, err, "failed to load image tar file") 103 defer loadResp.Body.Close() 104 for { 105 n, err := loadResp.Body.Read(buf) 106 if err != nil && err != io.EOF { 107 t.Fatalf("Error reading ImageLoad response: %v", err) 108 break 109 } 110 if n == 0 { 111 break 112 } 113 } 114 115 cid := container.Run(ctx, t, clientNoUserRemap, 116 container.WithImage(imageTag), 117 container.WithCmd("/sbin/getcap", "-n", "/bin/sleep"), 118 ) 119 logReader, err := clientNoUserRemap.ContainerLogs(ctx, cid, types.ContainerLogsOptions{ 120 ShowStdout: true, 121 }) 122 assert.NilError(t, err) 123 124 actualStdout := new(bytes.Buffer) 125 actualStderr := ioutil.Discard 126 _, err = stdcopy.StdCopy(actualStdout, actualStderr, logReader) 127 assert.NilError(t, err) 128 if strings.TrimSpace(actualStdout.String()) != "/bin/sleep cap_net_bind_service=eip" { 129 // Activate when fix is merged: https://github.com/moby/moby/pull/41724 130 //t.Fatalf("run produced invalid output: %q, expected %q", actualStdout.String(), "/bin/sleep cap_net_bind_service=eip") 131 // t.Logf("run produced invalid output (expected until #41724 merges): %q, expected %q", 132 // actualStdout.String(), 133 // "/bin/sleep cap_net_bind_service=eip") 134 } else { 135 // Shouldn't happen until fix is merged: https://github.com/moby/moby/pull/41724 136 t.Fatalf("run produced valid output (unexpected until #41724 merges): %q, expected %q", 137 actualStdout.String(), 138 "/bin/sleep cap_net_bind_service=eip") 139 } 140 }