`/home` incorrectly has ownership changed to `nonroot:nonroot` (`65532:65532`)
Describe the bug
Images (at least Debian 12 variants) seem to add /home/nonroot layer that modifies the ownership of /home:
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?
interesting, lemme go see
@thesayyn could this be happening in rules_distroless?
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 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?
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.
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?