Skip to content

Commit

Permalink
bake: deny access to local dockerfile for remote invocation with loca…
Browse files Browse the repository at this point in the history
…l context

we don't currently support reading a remote Dockerfile with a local
context when doing a remote invocation because we automatically derive
the dockerfile from the context atm. To avoid mistakenly reading a local
Dockerfile, we check if the Dockerfile exists locally and if so, we
error out.

Signed-off-by: CrazyMax <[email protected]>
  • Loading branch information
crazy-max committed Oct 19, 2023
1 parent 8973a1a commit 91e3978
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
22 changes: 21 additions & 1 deletion bake/bake.go
Original file line number Diff line number Diff line change
Expand Up @@ -1058,7 +1058,9 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
}
updateContext(&bi, inp)
if strings.HasPrefix(bi.DockerfilePath, "cwd://") {
bi.DockerfilePath = path.Clean(strings.TrimPrefix(bi.DockerfilePath, "cwd://"))
// If Dockerfile is local for a remote invocation, we first check if
// it's not outside the working directory and then resolve it to an
// absolute path.
if err := checkPath(bi.DockerfilePath); err != nil {
return nil, err
}
Expand All @@ -1067,6 +1069,24 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
if err != nil {
return nil, err
}
} else if !build.IsRemoteURL(bi.DockerfilePath) && strings.HasPrefix(bi.ContextPath, "cwd://") && (inp != nil && build.IsRemoteURL(inp.URL)) {
// We don't currently support reading a remote Dockerfile with a local
// context when doing a remote invocation because we automatically
// derive the dockerfile from the context atm:
//
// target "default" {
// context = BAKE_CMD_CONTEXT
// dockerfile = "Dockerfile.app"
// }
//
// > docker buildx bake https://github.com/foo/bar.git
// failed to solve: failed to read dockerfile: open /var/lib/docker/tmp/buildkit-mount3004544897/Dockerfile.app: no such file or directory
//
// To avoid mistakenly reading a local Dockerfile, we check if the
// Dockerfile exists locally and if so, we error out.
if _, err := os.Stat(filepath.Join(path.Clean(strings.TrimPrefix(bi.ContextPath, "cwd://")), bi.DockerfilePath)); err == nil {
return nil, errors.Errorf("reading a dockerfile for a remote build invocation is currently not supported")
}
}
if strings.HasPrefix(bi.ContextPath, "cwd://") {
bi.ContextPath = path.Clean(strings.TrimPrefix(bi.ContextPath, "cwd://"))
Expand Down
40 changes: 40 additions & 0 deletions tests/bake.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var bakeTests = []func(t *testing.T, sb integration.Sandbox){
testBakeRemoteCmdContextEscapeRoot,
testBakeRemoteCmdContextEscapeRelative,
testBakeRemoteDockerfileCwd,
testBakeRemoteLocalContextRemoteDockerfile,
}

func testBakeLocal(t *testing.T, sb integration.Sandbox) {
Expand Down Expand Up @@ -348,3 +349,42 @@ COPY foo /foo
)
require.Error(t, err, out)
}

func testBakeRemoteLocalContextRemoteDockerfile(t *testing.T, sb integration.Sandbox) {
bakefile := []byte(`
target "default" {
context = BAKE_CMD_CONTEXT
dockerfile = "Dockerfile.app"
}
`)
dockerfileApp := []byte(`
FROM scratch
COPY foo /foo
`)

dirSpec := tmpdir(
t,
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
)
dirSrc := tmpdir(
t,
fstest.CreateFile("Dockerfile.app", dockerfileApp, 0600),
fstest.CreateFile("foo", []byte("foo"), 0600),
)

git, err := gitutil.New(gitutil.WithWorkingDir(dirSpec))
require.NoError(t, err)

gitutil.GitInit(git, t)
gitutil.GitAdd(git, t, "docker-bake.hcl")
gitutil.GitCommit(git, t, "initial commit")
addr := gitutil.GitServeHTTP(git, t)

out, err := bakeCmd(
sb,
withDir(dirSrc),
withArgs(addr, "--set", "*.output=type=cacheonly"),
)
require.Error(t, err, out)
require.Contains(t, out, "reading a dockerfile for a remote build invocation is currently not supported")
}

0 comments on commit 91e3978

Please sign in to comment.