Skip to content

Directory permissions not always canonicalized #12786

@roberth

Description

@roberth

Looks like permissions are set in canonicaliseTimestampAndPermissions and 0444 is not updated to 0555 for directories.

E.g. 0554 is canonicalized, but not 0444.

Details
$ nix build -L --impure --expr 'with import ./. { };
let
  script = "mkdir -p $out/foo && touch $out/foo/bar && chmod o-x $out/foo";
  badDir = runCommand "bad-directory-permissions" { } script;
in runCommand "cat-file" { inherit badDir; } "stat $badDir/foo && cat $badDir/foo/bar && touch $out"'
cat-file>   File: /nix/store/42fsalzfn075vhhxbmrvbma37v3wf5wz-bad-directory-permissions/foo
cat-file>   Size: 6             Blocks: 0          IO Block: 4096   directory
cat-file> Device: 0,33  Inode: 242782051   Links: 1
cat-file> Access: (0555/dr-xr-xr-x)  Uid: (65534/  nobody)   Gid: (65534/ nogroup)
cat-file> Access: 2025-03-27 17:18:14.000000000 +0000
cat-file> Modify: 1970-01-01 00:00:01.000000000 +0000
cat-file> Change: 2025-03-27 17:18:14.682332844 +0000
cat-file>  Birth: 2025-03-27 17:18:14.682332844 +0000

Perhaps

-if (mode != 0444 && mode != 0555) {
+bool is_dir = S_ISDIR(st.st_mode);
+if ((mode != 0444 || is_dir) && mode != 0555) {
     mode = (st.st_mode & S_IFMT)
          | 0444
-         | (st.st_mode & S_IXUSR ? 0111 : 0);
+         | (st.st_mode & S_IXUSR || is_dir ? 0111 : 0);
     if (chmod(path.c_str(), mode) == -1)
         throw SysError("changing mode of '%1%' to %2$o", path, mode);
     }

Originally posted by @tie in NixOS/nixpkgs#393381 (comment)

Metadata

Metadata

Assignees

Labels

bugderivation-buildThe process of building an individual derivation (see also sandbox label)good first issueQuick win for first-time contributorsstoreIssues and pull requests concerning the Nix store
No fields configured for issues without a type.

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions