distroless icon indicating copy to clipboard operation
distroless copied to clipboard

`/home` incorrectly has ownership changed to `nonroot:nonroot` (`65532:65532`)

Open polarathene opened this issue 1 year ago • 6 comments

Describe the bug

Images (at least Debian 12 variants) seem to add /home/nonroot layer that modifies the ownership of /home:

image

Presumably that was unintentional and only meant to be applied to /home/nonroot?

To Reproduce

You can inspect the responsible layer where this change has been highlighted above via the dive tool:

docker run --rm -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  wagoodman/dive:latest \
  gcr.io/distroless/static-debian12:latest

While I've not done a diff of the file content, it does look rather similar to gcr.io/distroless/static-debian12:nonroot. That might explain why the /home/nonroot user is created?

docker inspect gcr.io/distroless/static-debian12:nonroot does show metadata differs, such as the default working directory and user to run as.

Expected behavior

/home should keep it's 0:0 ownership?

polarathene avatar Sep 05 '24 02:09 polarathene

interesting, lemme go see

loosebazooka avatar Sep 05 '24 13:09 loosebazooka

@thesayyn could this be happening in rules_distroless?

loosebazooka avatar Sep 05 '24 14:09 loosebazooka

This is probably due to rules_distroless home rule. It creates the home directory just in case which is not needed in this case

thesayyn avatar Oct 02 '24 15:10 thesayyn

@thesayyn I don't mind the /home/nonroot directory being created, but /home itself should not have the UID/GID for nonroot? So perhaps the rule should keep /home as 0:0?

polarathene avatar Oct 02 '24 19:10 polarathene

According to https://github.com/GoogleContainerTools/rules_distroless/blob/35a7d5a37b34e68f1d58d7e452147afe941f3e5a/distroless/private/home.bzl#L18-L26

home rule only creates subdirectories under /home with desired permissions, so i don't know where the problem is.

thesayyn avatar Oct 03 '24 18:10 thesayyn

so i don't know where the problem is.

I'm not familiar with the build system itself, but I do know if using COPY --link in a Dockerfile this has the effect of treating the source as FROM scratch stage of it's own implicitly that is then a COPY to the stage invoking --link. The FROM scratch has that source path copied to it at the target path.

When the target location for the COPY --link is a subpath this would default ownership of any parent directories in the path to 0:0 unless --chown was also provided to COPY, which would apply to those parent directories too (except when --chmod was present). That inconsistency is a bug AFAIK 🤷‍♂️

Anyway, at this point of the build with a Dockerfile, those parent paths ownership would overwrite the equivalent paths on the actual stage visible in the Dockerfile. I ran into this issue in the past, so I can provide links to upstream issues and more details if useful?

I was under the impression that the distroless images here are built without a Dockerfile? But perhaps this same issue applies with composition of layers with tarballs.


Perhaps this is relevant with flatten?:

https://github.com/GoogleContainerTools/rules_distroless/blob/35a7d5a37b34e68f1d58d7e452147afe941f3e5a/examples/flatten/BUILD.bazel#L50-L65

assert_tar_listing(
    name = "test_flatten",
    actual = "flatten",
    expected = """\
#mtree
./etc time=0.0 mode=755 gid=0 uid=0 type=dir
./etc/passwd time=0.0 mode=644 gid=0 uid=0 type=file size=34
./examples time=1672560000.0 mode=755 gid=0 uid=0 type=dir
./examples/flatten time=1672560000.0 mode=755 gid=0 uid=0 type=dir
./examples/flatten/dir time=1672560000.0 mode=755 gid=0 uid=0 type=dir
./examples/flatten/dir/changelog time=1672560000.0 mode=755 gid=0 uid=0 type=file size=0
./examples/flatten/dir/sub time=1672560000.0 mode=755 gid=0 uid=0 type=dir
./examples/flatten/dir/sub/content.txt time=1672560000.0 mode=755 gid=0 uid=0 type=file size=0
./home/nonroot time=0.0 mode=700 gid=666 uid=666 type=dir
./root time=0.0 mode=700 gid=0 uid=0 type=dir
""",

https://github.com/GoogleContainerTools/rules_distroless/blob/35a7d5a37b34e68f1d58d7e452147afe941f3e5a/examples/flatten/BUILD.bazel#L41-L48

flatten(
    name = "flatten",
    tars = [
        ":passwd",
        ":home",
        ":source",
    ],
)

https://github.com/GoogleContainerTools/rules_distroless/blob/35a7d5a37b34e68f1d58d7e452147afe941f3e5a/examples/flatten/BUILD.bazel#L19-L33

home(
    name = "home",
    dirs = [
        {
            "home": "root",
            "uid": 0,
            "gid": 0,
        },
        {
            "home": "home/nonroot",
            "uid": 666,
            "gid": 666,
        },
    ],
)

Something is either creating /home or overwriting it's ownership to the UID/GID of nonroot. I noticed the test shown doesn't verify the /home ownership itself, so perhaps that'll help identify if it's happened by that point?

polarathene avatar Oct 03 '24 21:10 polarathene