Skip to content

Commit

Permalink
remote,build: error if containerignore is symlink
Browse files Browse the repository at this point in the history
Drop support for remote use-cases when `.containerignore` or
`.dockerignore` is a symlink pointing to arbitrary location on host.

Signed-off-by: Aditya R <arajan@redhat.com>
  • Loading branch information
flouthoc committed Oct 28, 2022
1 parent 47bcd10 commit 17a6bd0
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 2 deletions.
32 changes: 30 additions & 2 deletions pkg/bindings/images/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -743,11 +743,39 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) {
return rc, nil
}

func errIfSymlinkOutsideRoot(root, path string) error {
pathInfo, err := os.Lstat(path)
if err == nil {
if pathInfo.Mode()&os.ModeSymlink != 0 {
// If resolved symlink is inside build context just return
resolvedPath, err := filepath.EvalSymlinks(path)
if err != nil {
return fmt.Errorf("unable to resolve symlink %s: %w", path, err)
}
if strings.HasPrefix(resolvedPath, root) {
return nil
}
return fmt.Errorf("%s cannot be a symlink outside of build context", path)
}
}
return nil
}

func parseDockerignore(root string) ([]string, error) {
ignore, err := os.ReadFile(filepath.Join(root, ".containerignore"))
path := filepath.Join(root, ".containerignore")
err := errIfSymlinkOutsideRoot(root, path)
if err != nil {
return nil, err
}
ignore, err := os.ReadFile(path)
if err != nil {
var dockerIgnoreErr error
ignore, dockerIgnoreErr = os.ReadFile(filepath.Join(root, ".dockerignore"))
path = filepath.Join(root, ".dockerignore")
symlinkErr := errIfSymlinkOutsideRoot(root, path)
if symlinkErr != nil {
return nil, symlinkErr
}
ignore, dockerIgnoreErr = os.ReadFile(path)
if dockerIgnoreErr != nil && !os.IsNotExist(dockerIgnoreErr) {
return nil, err
}
Expand Down
1 change: 1 addition & 0 deletions test/e2e/build/containerignore-symlink/.dockerignore
2 changes: 2 additions & 0 deletions test/e2e/build/containerignore-symlink/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
FROM alpine
COPY / /dir
Empty file.
Empty file.
21 changes: 21 additions & 0 deletions test/e2e/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@ var _ = Describe("Podman build", func() {
// If the context directory is pointing at a file and not a directory,
// that's a no no, fail out.
It("podman build context directory a file", func() {
// Create a random file where symlink must be resolved
// but build should not be able to access it.
f, err := os.Create(filepath.Join("/tmp", "private_file"))
Expect(err).ToNot(HaveOccurred())
defer f.Close()

session := podmanTest.Podman([]string{"build", "--pull=never", "build/context_dir_a_file"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(125))
Expand Down Expand Up @@ -412,6 +418,21 @@ RUN find /test`, ALPINE)
Expect(session.OutputToString()).To(ContainSubstring("/test/dummy"))
})

It("podman remote build must not allow symlink for ignore files", func() {
if IsRemote() {
podmanTest.StopRemoteService()
podmanTest.StartRemoteService()
} else {
Skip("Only valid at remote test")
}

session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "build/containerignore-symlink/"})
session.WaitWithDefaultTimeout()
output := session.ErrorToString()
Expect(output).To(ContainSubstring(".dockerignore cannot be a symlink"))
Expect(session).Should(Exit(125))
})

It("podman remote test container/docker file is not at root of context dir", func() {
if IsRemote() {
podmanTest.StopRemoteService()
Expand Down

0 comments on commit 17a6bd0

Please sign in to comment.