docker / for-mac

Bug reports for Docker Desktop for Mac
https://www.docker.com/products/docker#/mac
2.44k stars 118 forks source link

Synchronized file shares modifies file permissions #7452

Closed Devon-Dickson closed 1 month ago

Devon-Dickson commented 1 month ago

Description

An automatically generated Synchronized file share was created for a volume that contains a private key managed by Teleport. Every time I run tsh login the key in the docker container is granted group and global read access. After deleting the file share in Docker Desktop settings, this undesired behavior no longer exists.

Reproduce

  1. tsh login
  2. Note that the private key on the host file system has just owner read/write permissions.
  3. Start docker container
  4. Note that the private key inside the docker container now also has group and global read permissions.
  5. (Optional) chmod the key in Docker to 600
  6. (Optional) Run tsh login again
  7. (Optional) Note that the key again has group and global read permissions.

Expected behavior

The private key in the docker container should have the same permissions as on the host system.

docker version

Client: Version: 27.2.0 API version: 1.47 Go version: go1.21.13 Git commit: 3ab4256 Built: Tue Aug 27 14:14:45 2024 OS/Arch: darwin/arm64 Context: desktop-linux

Server: Docker Desktop 4.34.3 (170107) Engine: Version: 27.2.0 API version: 1.47 (minimum version 1.24) Go version: go1.21.13 Git commit: 3ab5c7d Built: Tue Aug 27 14:15:41 2024 OS/Arch: linux/arm64 Experimental: false containerd: Version: 1.7.20 GitCommit: 8fc6bcff51318944179630522a095cc9dbf9f353 runc: Version: 1.1.13 GitCommit: v1.1.13-0-g58aa920 docker-init: Version: 0.19.0 GitCommit: de40ad0

docker info

Client: Version: 27.2.0 Context: desktop-linux Debug Mode: false Plugins: buildx: Docker Buildx (Docker Inc.) Version: v0.16.2-desktop.1 Path: /Users/devon/.docker/cli-plugins/docker-buildx compose: Docker Compose (Docker Inc.) Version: v2.29.2-desktop.2 Path: /Users/devon/.docker/cli-plugins/docker-compose debug: Get a shell into any image or container (Docker Inc.) Version: 0.0.34 Path: /Users/devon/.docker/cli-plugins/docker-debug desktop: Docker Desktop commands (Alpha) (Docker Inc.) Version: v0.0.15 Path: /Users/devon/.docker/cli-plugins/docker-desktop dev: Docker Dev Environments (Docker Inc.) Version: v0.1.2 Path: /Users/devon/.docker/cli-plugins/docker-dev extension: Manages Docker extensions (Docker Inc.) Version: v0.2.25 Path: /Users/devon/.docker/cli-plugins/docker-extension feedback: Provide feedback, right in your terminal! (Docker Inc.) Version: v1.0.5 Path: /Users/devon/.docker/cli-plugins/docker-feedback init: Creates Docker-related starter files for your project (Docker Inc.) Version: v1.3.0 Path: /Users/devon/.docker/cli-plugins/docker-init sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc.) Version: 0.6.0 Path: /Users/devon/.docker/cli-plugins/docker-sbom scout: Docker Scout (Docker Inc.) Version: v1.13.0 Path: /Users/devon/.docker/cli-plugins/docker-scout

Server: Containers: 4 Running: 3 Paused: 0 Stopped: 1 Images: 4 Server Version: 27.2.0 Storage Driver: overlay2 Backing Filesystem: extfs Supports d_type: true Using metacopy: false Native Overlay Diff: true userxattr: false Logging Driver: json-file Cgroup Driver: cgroupfs Cgroup Version: 2 Plugins: Volume: local Network: bridge host ipvlan macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog Swarm: inactive Runtimes: io.containerd.runc.v2 runc Default Runtime: runc Init Binary: docker-init containerd version: 8fc6bcff51318944179630522a095cc9dbf9f353 runc version: v1.1.13-0-g58aa920 init version: de40ad0 Security Options: seccomp Profile: unconfined cgroupns Kernel Version: 6.10.4-linuxkit Operating System: Docker Desktop OSType: linux Architecture: aarch64 CPUs: 10 Total Memory: 23.44GiB Name: docker-desktop ID: 2aa5cbfa-c768-45c3-bd1b-acb23acb6378 Docker Root Dir: /var/lib/docker Debug Mode: false HTTP Proxy: http.docker.internal:3128 HTTPS Proxy: http.docker.internal:3128 No Proxy: hubproxy.docker.internal Labels: com.docker.desktop.address=unix:///Users/devon/Library/Containers/com.docker.docker/Data/docker-cli.sock Experimental: false Insecure Registries: hubproxy.docker.internal:5555 127.0.0.0/8 Live Restore Enabled: false

WARNING: daemon is not using the default seccomp profile

Diagnostics ID

0D0F959B-2A33-422D-A844-DE8D4F0FF6FC/20241009170442

Additional Info

No response

xenoscopic commented 1 month ago

Hi @Devon-Dickson, are you seeing the same issue with Virtiofs-based filesharing? I would expect that the same issue exists with all of the Docker file sharing mechanisms. This is something we're unlikely to change in Synchronized File Shares due to a desire for backward compatibility with Virtiofs, gRPC-FUSE, and osxfs, but if there's deviation in the behavior then we can have a look.

xenoscopic commented 1 month ago

(Apologies, closed accidentally)

Devon-Dickson commented 1 month ago

It does appear to occur on both gRPC-FUSE and virtiofs.

Maintaining backwards compatibility is reasonable, so I'll accept that I'll just have to keep this setting disabled. I am curious if you have a clear explanation for what's happening though, since this did take a long time to track down and resolve.

xenoscopic commented 1 month ago

I believe there were two reasons for it historically:

First, the Docker Desktop VM doesn't have the same UID/GIDs as the host system, so file ownership has to be set to a default value (though changes to this ownership are persisted to the host as extended attributes). This default ownership was (sensibly) root/root, but that meant that non-privileged containers had no way to access the files. To work around this, wider default permissions (such as 0777/0666) were used.

Second, or rather as a detail of the first point, containers typically run as different UIDs/GIDs (such as root, 33, 82, and 1000). This meant that there was never going to be a dynamic value that worked well in multi-container setups (like a Compose project).

For Synchronized File Shares, we actually use a dynamic ownership mechanism, where files shared through an SFS mount look as if they're owned by the UID/GID of whatever process is asking. This makes multi-container interop on the same bind mount path much easier, since they aren't clobbering ownership or permissions on files in a way that would break other containers.