Skip to content

image: Normalize modes again when an image is finalized - #313

Open
mvo5 wants to merge 1 commit into
amutable-systems:mainfrom
mvo5:fix-layer-dir-mode
Open

mvo5 wants to merge 1 commit into
amutable-systems:mainfrom
mvo5:fix-layer-dir-mode

Conversation

@mvo5

@mvo5 mvo5 commented Oct 15, 2026

Copy link
Copy Markdown
Member

I have only lightly reviewed this, most is claude. I think this means we can also drop the special case for /tmp, /var/tmp but I leave that to you I wanted to be conservative here.


A layer normalizes what it captures, but a layer travels through Buck as a directory artifact, and Buck stores no mode beyond the executable bit. A layer materialized from the cache therefore has every directory in the mode the host's umask allows: 0775 under a developer's 0002, 0755 under CI's 0022. sshd refuses a group-writable /usr/share/empty.sshd, so an image built from cached layers on such a host boots without a working SSH server, while CI never sees it.

finalize.image() restored /tmp's 1777 as the one mode a layer cannot carry, but left the rest to the layers. Normalize the whole mounted stack there, the last point before the image is written, and only chmod what differs so the overlay copies up nothing it need not. The sysext driver writes /opt and the extension-release after that point, so it normalizes what it creates.

layer.py uses the shared function; its test moves to finalize_test.py.

A layer normalizes what it captures, but a layer travels through Buck as a
directory artifact, and Buck stores no mode beyond the executable bit. A
layer materialized from the cache therefore has every directory in the mode
the host's umask allows: 0775 under a developer's 0002, 0755 under CI's 0022.
sshd refuses a group-writable /usr/share/empty.sshd, so an image built from
cached layers on such a host boots without a working SSH server, while CI
never sees it.

finalize.image() restored /tmp's 1777 as the one mode a layer cannot carry,
but left the rest to the layers. Normalize the whole mounted stack there, the
last point before the image is written, and only chmod what differs so the
overlay copies up nothing it need not. The sysext driver writes /opt and the
extension-release after that point, so it normalizes what it creates.

layer.py uses the shared function; its test moves to finalize_test.py.
@martinpitt

Copy link
Copy Markdown
Member

@mvo5 whoops! I think we saw exactly the same breakage around the same time, and I sent #314 for this (landed now). Do you still actually need this with current main?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants