Permissions of /tmp are set to 755 after a bind mount is placed under /tmp under specific conditions
Issue Description
Under specific situations, podman build (does not happen when running buildah directly) resets the permissions of /tmp to 755. Those conditions seem to be:
- A folder already exists under
/tmp(e.g./tmp/a) - In the same RUN instruction, a bind mount is placed under
/tmp(e.g. mounted at/tmp/b) and a file is created under the pre-existing folder (e.g./tmp/a/example.txt).
I became aware of this problem due to an existing issue with devcontainers caused by this bug. Here is the relevant devcontainers issue: https://github.com/devcontainers/images/issues/1556.
Steps to reproduce the issue
- Create an empty folder with the following
Containerfile:
FROM docker.io/library/ubuntu:22.04
RUN ls -la /tmp/
RUN mkdir -p /tmp/a/
RUN --mount=type=bind,source=.,target=/tmp/b/ touch /tmp/a/example.txt
RUN ls -la /tmp/
- Run
podman build --no-cache . - See the permissions of
/tmpprinted in the lastls -la /tmp.
Describe the results you received
Running podman build --no-cache . yields the following logs:
STEP 1/5: FROM docker.io/library/ubuntu:22.04
STEP 2/5: RUN ls -la /tmp/
total 0
drwxrwxrwt 1 root root 0 Oct 1 02:10 .
dr-xr-xr-x 1 root root 18 Nov 13 21:36 ..
--> 9400d67ec242
STEP 3/5: RUN mkdir -p /tmp/a/
--> c06a6049730a
STEP 4/5: RUN --mount=type=bind,source=.,target=/tmp/b/ touch /tmp/a/example.txt
--> c290d15ac7bd
STEP 5/5: RUN ls -la /tmp/
total 0
drwxr-xr-x 1 root root 2 Nov 13 21:36 .
dr-xr-xr-x 1 root root 18 Nov 13 21:36 ..
drwxr-xr-x 1 root root 22 Nov 13 21:36 a
COMMIT
--> 96f5267ab511
96f5267ab5112e128eeddf6307f603f31e3430104f99872dff44868f2a7aa75b
As you can see from the line drwxr-xr-x 1 root root 2 Nov 13 21:36 ., the permissions of the /tmp directory are set to 755 even though no chmod command was executed.
Describe the results you expected
I expected the result yielded by buildah build --no-cache .:
STEP 1/5: FROM docker.io/library/ubuntu:22.04
STEP 2/5: RUN ls -la /tmp/
total 0
drwxrwxrwt 1 root root 0 Oct 1 02:10 .
dr-xr-xr-x 1 root root 24 Nov 13 21:36 ..
STEP 3/5: RUN mkdir -p /tmp/a/
STEP 4/5: RUN --mount=type=bind,source=.,target=/tmp/b/ touch /tmp/a/example.txt
STEP 5/5: RUN ls -la /tmp/
total 0
drwxrwxrwt 1 root root 2 Nov 13 21:36 .
dr-xr-xr-x 1 root root 30 Nov 13 21:36 ..
drwxr-xr-x 1 root root 22 Nov 13 21:36 a
COMMIT
--> dcba70ab0e9d
dcba70ab0e9db48ed7c0561025b894e228d0d0bc3ce3817285cdb555b295a533
As you can see, the /tmp directory has the correct permissions.
podman version output
Client: Podman Engine
Version: 5.7.0
API Version: 5.7.0
Go Version: go1.25.2
Built: Tue Jan 1 00:00:00 1980
OS/Arch: linux/amd64
podman info output
host:
arch: amd64
buildahVersion: 1.42.0
cgroupControllers:
- cpu
- io
- memory
- pids
cgroupManager: systemd
cgroupVersion: v2
conmon:
package: Unknown
path: /nix/store/6ar9ipnqm47pfnvgh036d8jbwj5dfwj0-podman-helper-binary-wrapper/bin/conmon
version: 'conmon version 2.1.13, commit: '
cpuUtilization:
idlePercent: 94.02
systemPercent: 1.17
userPercent: 4.81
cpus: 16
databaseBackend: sqlite
distribution:
codename: xantusia
distribution: nixos
version: "25.11"
eventLogger: journald
freeLocks: 2037
hostname: AAAAAAAA
idMappings:
gidmap:
- container_id: 0
host_id: 100
size: 1
- container_id: 1
host_id: 100000
size: 65536
uidmap:
- container_id: 0
host_id: 1000
size: 1
- container_id: 1
host_id: 100000
size: 65536
kernel: 6.17.7
linkmode: dynamic
logDriver: journald
memFree: 5910265856
memTotal: 32267067392
networkBackend: netavark
networkBackendInfo:
backend: netavark
dns:
package: Unknown
path: /nix/store/9y4b9qj24z3wkyf5dwr8s8ycffgmr2rn-podman-5.7.0/libexec/podman/aardvark-dns
version: aardvark-dns 1.16.0
package: Unknown
path: /nix/store/9y4b9qj24z3wkyf5dwr8s8ycffgmr2rn-podman-5.7.0/libexec/podman/netavark
version: netavark 1.16.1
ociRuntime:
name: crun
package: Unknown
path: /nix/store/6ar9ipnqm47pfnvgh036d8jbwj5dfwj0-podman-helper-binary-wrapper/bin/crun
version: |-
crun version 1.24
commit: 1.24
rundir: /run/user/1000/crun
spec: 1.0.0
+SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +CRIU +YAJL
os: linux
pasta:
executable: /nix/store/9y4b9qj24z3wkyf5dwr8s8ycffgmr2rn-podman-5.7.0/libexec/podman/pasta
package: Unknown
version: |
pasta 2025_09_19.623dbf6
Copyright Red Hat
GNU General Public License, version 2 or later
<https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
remoteSocket:
exists: true
path: /run/user/1000/podman/podman.sock
rootlessNetworkCmd: pasta
security:
apparmorEnabled: false
capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
rootless: true
seccompEnabled: true
seccompProfilePath: ""
selinuxEnabled: false
serviceIsRemote: false
slirp4netns:
executable: ""
package: ""
version: ""
swapFree: 38654701568
swapTotal: 38654701568
uptime: 0h 58m 51.00s
variant: ""
plugins:
authorization: null
log:
- k8s-file
- none
- passthrough
- journald
network:
- bridge
- macvlan
- ipvlan
volume:
- local
registries:
search:
- docker.io
- quay.io
store:
configFile: /home/lima/.config/containers/storage.conf
containerStore:
number: 10
paused: 0
running: 0
stopped: 10
graphDriverName: overlay
graphOptions: {}
graphRoot: /home/lima/.local/share/containers/storage
graphRootAllocated: 961024098304
graphRootUsed: 761307258880
graphStatus:
Backing Filesystem: btrfs
Native Overlay Diff: "true"
Supports d_type: "true"
Supports shifting: "false"
Supports volatile: "true"
Using metacopy: "false"
imageCopyTmpDir: /var/tmp
imageStore:
number: 924
runRoot: /run/user/1000/containers
transientStore: false
volumePath: /home/lima/.local/share/containers/storage/volumes
version:
APIVersion: 5.7.0
Built: 315532800
BuiltTime: Tue Jan 1 00:00:00 1980
GitCommit: ""
GoVersion: go1.25.2
Os: linux
OsArch: linux/amd64
Version: 5.7.0
Provide your storage.conf
[storage]
driver = "overlay"
graphroot = "/var/lib/containers/storage"
runroot = "/run/containers/storage"
Podman in a container
No
Privileged Or Rootless
Rootless
Upstream Latest Release
Yes
Installation Source
Distribution package (DNF, apt, yay)
Additional environment details
Running NixOS unstable, with a patch to upgrade Podman to version 5.7.0.
Additional information
The issue only happens with podman build and not with buildah build.
This looks like a consequence of us not adding an entry for "tmp" in the layer that creates "tmp/a/example.txt" when the --layers flag is used (the flag is enabled by default for podman build but not buildah build), in combination with using the overlay storage driver.
In the overlay driver, the contents of each layer are stored in a separate directory tree. When the layer that includes "tmp/a/example.txt" is being written to disk, because the layer blob doesn't include an entry that would cause "tmp" to have already been created for that layer with known permissions and ownership, the directory has to be created by the driver, and the driver currently uses the same default permissions and ownership for any such directory that it has to create. I started working on something to address this in https://github.com/containers/storage/pull/1653, but didn't finish it.
Okay, that's good to know!
By the way, while investigating this bug, I found another example, but with a weirder behavior - sometimes the permissions are right, and other times the permissions are wrong:
FROM docker.io/library/ubuntu:22.04
RUN ls -la /tmp/
RUN mkdir -p /tmp/a/
RUN --mount=type=bind,source=.,target=/tmp/b/ touch /tmp/example.txt
RUN ls -la /tmp/
The only difference is that the file is created directly under /tmp instead of /tmp/a.
Sometimes the /tmp directory has 755 permissions, but there are runs in which it has 1777 permissions. And the weirder thing is, this doesn't seem to happen without the RUN mkdir -p /tmp/a/ instruction.
Is this the same bug, or should I file another issue?
A friendly reminder that this issue had no activity for 30 days.
Ping to prevent the issue from going stale. I also observe this issue when installing stuff via apt using podman buildx (buildah). It tries to copy some GPG keys to /tmp for verification, which fails and prevents the installation of packages.