Thanks to visit codestin.com
Credit goes to github.com

Skip to content

When building an image symbolic links to directories are copied as clones of the directories instead of as symbolic links #2193

Closed
@andrian-sevastyanov

Description

@andrian-sevastyanov

When building an image, symbolic links to directories are copied as clones of the directories instead of as symbolic links.

This is problematic for the following reasons:

  1. Security issues and incorrectness. A symlink to /some/unintended/absolute/path/with/sensitive/data/ can end up resolving to a directory outside of the build directory, and so a clone of a directory with sensitive data can end up in the resulting Docker image. A less dangerous version of this issue may be that the container contents will be incorrect.
  2. Duplication of data. This can mean bloated Docker images. Additionally, this can cause issues where some code assumes that modifying data in a symlinked directory will result in changes in all places where that data is being used.

Replicating The Issue

Source directory structure (note a single large file and two symlinks pointing to the directory that contains it):

.
├── [  33]  Dockerfile
└── [  96]  fileSystem
    └── [ 160]  stuff
        ├── [  96]  subdir
        │   └── [ 95M]  equals.txt
        ├── [   7]  symlink_to_subdir -> subdir/
        └── [   7]  symlink_to_subdir2 -> subdir/

Dockerfile contents:

FROM scratch
COPY fileSystem/* .

If I run docker build . from CLI the resulting image is ~100MB in size.
However, when I run the following code, the resulting image is triple the size:

package test_client;

import java.io.File;
import java.io.IOException;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.core.DockerClientImpl;
import com.github.dockerjava.api.command.BuildImageCmd;
import com.github.dockerjava.api.command.BuildImageResultCallback;
import com.github.dockerjava.core.DockerClientConfig;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;

class DockerClientTest {
        public static void main(String[] args) throws IOException {
                String buildDir = args[0];

                System.out.println("Build directory: " + buildDir);

                DockerClientConfig clientConfig = DefaultDockerClientConfig.createDefaultConfigBuilder().build();

                DockerClient client = DockerClientImpl.getInstance(
                        clientConfig,
                        new ApacheDockerHttpClient.Builder()
                                .dockerHost(clientConfig.getDockerHost())
                                .sslConfig(clientConfig.getSSLConfig())
                                .build()
                );

                String imageId;
                try (BuildImageCmd buildImageCmd = client.buildImageCmd(new File(buildDir));
                    BuildImageResultCallback callback = new BuildImageResultCallback()) {
                    try (BuildImageResultCallback resultCallback = buildImageCmd.exec(callback)) {
                        imageId = resultCallback.awaitImageId();
                    }
                }
                System.out.println(String.format("Built image: %s", imageId));
        }
}

Potential Fix

I believe the fix for this would be simple; however, I haven't gotten around to it as I had some issues building the library locally.

The check in this line can be changed from f.isDirectory() to something similar to f.isDirectory() && !Files.isSymbolicLink(Paths.get(f.getAbsolutePath())) and this should resolve the issue.

There is a chance I will create a PR for this issue; however, if someone gets to this first it would be appreciated.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions