Skip to content

libstore: always canonicalize directory permissions#13526

Merged
tomberek merged 1 commit intoNixOS:masterfrom
philiptaron:issue-12786/canonicaliseTimestampAndPermissions-on-dir-better
Aug 6, 2025
Merged

libstore: always canonicalize directory permissions#13526
tomberek merged 1 commit intoNixOS:masterfrom
philiptaron:issue-12786/canonicaliseTimestampAndPermissions-on-dir-better

Conversation

@philiptaron
Copy link
Contributor

@philiptaron philiptaron commented Jul 23, 2025

Motivation

Prior to this patch, mode 0444 is not updated to 0555 for directories. That means for instance 0554 is canonicalized, but not 0444.

I don't believe this has any implications for backwards compatibility, because directories do not have permissions in NAR format and so are always 0555 after de-serialization, and store paths with wrong permissions can’t be copied to another host.

This patch was proposed by @roberth in #12786.

I'd love to add a unit test for this, but I saw no existing examples for code in this file.

Context

Fixes #12786.


Add 👍 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

@philiptaron philiptaron requested a review from tomberek July 23, 2025 18:33
@philiptaron philiptaron marked this pull request as ready for review July 23, 2025 20:03
@philiptaron philiptaron requested a review from Ericson2314 as a code owner July 23, 2025 20:03
@xokdvium xokdvium added this to Nix team Aug 3, 2025
@github-project-automation github-project-automation bot moved this to Triage in Nix team Aug 3, 2025
Prior to this patch, mode 0444 is not updated to 0555 for directories.
That means for instance 0554 is canonicalized, but not 0444.

We don't believe this has any implications for backwards compatibility,
because directories do not have permissions in NAR format and so are
always 0555 after deserialization, and store paths with wrong
permissions can’t be copied to another host.

Co-authored-by: Robert Hensing <robert@roberthensing.nl>
@tomberek tomberek force-pushed the issue-12786/canonicaliseTimestampAndPermissions-on-dir-better branch from 32f9a5f to c38987e Compare August 6, 2025 15:58
@edolstra edolstra removed this from Nix team Aug 6, 2025
@tomberek tomberek merged commit 55f6ff3 into NixOS:master Aug 6, 2025
14 checks passed
@philiptaron philiptaron deleted the issue-12786/canonicaliseTimestampAndPermissions-on-dir-better branch August 6, 2025 20:30
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2025-08-06-nix-team-meeting-minutes-239-240/67694/2

@DavHau
Copy link
Member

DavHau commented Nov 25, 2025

Nix trying to chmod things has been a pain point for us on a recurring basis. In some environments nix simply doesn't have the permissions to chmod and crashes as a result.

This change makes it worse, as this problem now appears more often. Specifically this is a problem in artificial testing environments like VMs or containers.

Can we just change nix to try to chmod, and print a warning if it did not work instead of crashing?

cc @Mic92

@roberth
Copy link
Member

roberth commented Nov 25, 2025

Bailing is safer than continuing. I'd require an opt-in for such behavior.

@philiptaron
Copy link
Contributor Author

Specifically this is a problem in artificial testing environments like VMs or containers.

What's the underlying filesystem that doesn't like chmod?

lorddevi pushed a commit to lorddevi/clan-core that referenced this pull request Dec 1, 2025
Override the `Nix` version used by `nixos-anywhere` used by the `clan`
CLI.

Nix 2.31 introduced stricter permission canonicalization that unconditionally
chmods directories to 0555 during `nix copy` [^nix-perms] operations.
In the nixos test we have the following file overlay file structure
`findmnt` (elided and compacted for brevity):

```shell-session
├─/nix/.ro-store  nix-store  9p         rw,relatime,cache=f,access=client,msize=16384,trans=virtio
├─/nix/.rw-store  tmpfs      tmpfs      rw,relatime,mode=755
├─/nix/store      overlay    overlay    rw,relatime,lowerdir=/mnt-root/nix/.ro-store,upperdir=/mnt-root/nix/.rw-store/upper,workdir=/mnt-root/nix/.rw-store/work,uuid=on
│ └─/nix/store    overlay    overlay    ro,nosuid,nodev,relatime,lowerdir=/mnt-root/nix/.ro-store,upperdir=/mnt-root/nix/.rw-store/upper,workdir=/mnt-root/nix/.rw-store/work,uuid=on
```

This means that the host store is shared and new paths are written to
the writeable layer, but old paths that don't need to be written will be
canonicalized, which fails, because we don't have the permissions to
change the permissions of the read only layer.

The error message we got:

```shell-session
copying path '/nix/store/0dqzmxlgkmw057ffz0cpcbszg17yfmrk-publicsuffix-list-0-unstable-2025-08-28' to 'ssh://root@localhost'...
error: chmod "/nix/store/0dqzmxlgkmw057ffz0cpcbszg17yfmrk-publicsuffix-list-0-unstable-2025-08-28": Operation not permitted
```

[^nix-perms]: Nix Permission change: NixOS/nix#13526
@DavHau
Copy link
Member

DavHau commented Dec 3, 2025

Specifically this is a problem in artificial testing environments like VMs or containers.

What's the underlying filesystem that doesn't like chmod?

See lorddevi/clan-core@a933061

clan-infra-bot bot pushed a commit to clan-lol/clan-core that referenced this pull request Dec 4, 2025
Override the `Nix` version used by `nixos-anywhere` used by the `clan`
CLI.

Nix 2.31 introduced stricter permission canonicalization that unconditionally
chmods directories to 0555 during `nix copy` [^nix-perms] operations.
In the nixos test we have the following file overlay file structure
`findmnt` (elided and compacted for brevity):

```shell-session
├─/nix/.ro-store  nix-store  9p         rw,relatime,cache=f,access=client,msize=16384,trans=virtio
├─/nix/.rw-store  tmpfs      tmpfs      rw,relatime,mode=755
├─/nix/store      overlay    overlay    rw,relatime,lowerdir=/mnt-root/nix/.ro-store,upperdir=/mnt-root/nix/.rw-store/upper,workdir=/mnt-root/nix/.rw-store/work,uuid=on
│ └─/nix/store    overlay    overlay    ro,nosuid,nodev,relatime,lowerdir=/mnt-root/nix/.ro-store,upperdir=/mnt-root/nix/.rw-store/upper,workdir=/mnt-root/nix/.rw-store/work,uuid=on
```

This means that the host store is shared and new paths are written to
the writeable layer, but old paths that don't need to be written will be
canonicalized, which fails, because we don't have the permissions to
change the permissions of the read only layer.

The error message we got:

```shell-session
copying path '/nix/store/0dqzmxlgkmw057ffz0cpcbszg17yfmrk-publicsuffix-list-0-unstable-2025-08-28' to 'ssh://root@localhost'...
error: chmod "/nix/store/0dqzmxlgkmw057ffz0cpcbszg17yfmrk-publicsuffix-list-0-unstable-2025-08-28": Operation not permitted
```

[^nix-perms]: Nix Permission change: NixOS/nix#13526
@philiptaron
Copy link
Contributor Author

What's the configuration of the Nix store in nix.conf or equivalent? I'm still having trouble formulating the setup correctly in my head (and ideally, getting a reproducer in real life.)

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.

Directory permissions not always canonicalized

5 participants