Skip to content

Conversation

@edolstra
Copy link
Collaborator

@edolstra edolstra commented Jan 16, 2026

Motivation

Context

Summary by CodeRabbit

  • Bug Fixes

    • Fixed readDir builtin to properly error when reading non-existent or non-directory paths.
    • Improved substituter efficiency by stopping after finding path info.
    • Enhanced sandbox DNS configuration support on macOS.
  • Documentation

    • Added maintainer GPG key documentation for release verification.
  • Chores

    • Bumped version to 2.33.1.
    • Improved release workflow to use standardized GitHub Actions process.

✏️ Tip: You can customize this high-level summary in your review settings.

edolstra and others added 30 commits December 10, 2025 23:00
…tenance

[Backport 2.33-maintenance] [libstore]: Fix a heap-use-after-free bug
Unfortunately previous tarball caches had loose objects written to
them and subsequent switch to thin packfiles. This results in possibly
broken thin packfiles when the loose objects backend is disabled. Thin
packfiles do not necessarily contain the whole closure of objects.
When packfilesOnly is true we end up with an inconsistent state where
a tree lives in a packfiles which refers to a blob in the loose objects
backend.

In the future we might want to nuke old cache directories and repack
the tarball cache.

(cherry picked from commit 0ffe83a)
…tenance

libfetchers: Bump tarball-cache version to v2 [backport 2.33]
Bumps [korthout/backport-action](https://github.com/korthout/backport-action) from 3.4.1 to 4.0.1.
- [Release notes](https://github.com/korthout/backport-action/releases)
- [Commits](korthout/backport-action@d074166...c656f5d)

---
updated-dependencies:
- dependency-name: korthout/backport-action
  dependency-version: 4.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
(cherry picked from commit 4227d24)
…tenance

[Backport 2.33-maintenance] build(deps): bump korthout/backport-action from 3.4.1 to 4.0.1
- Skip packages that don't build for Windows when building for windows
- Automatically disable kaitai / json schema, fixing todo
- Skip native build of Nix for manual

(cherry picked from commit a5edc2d)
…tenance

[Backport 2.33-maintenance] Fix up dev shell in a few ways
There are other types of sockets.

(cherry picked from commit 79750a3)
These functions use `SOCKET` not `int`, despite them being unix
functions.

(cherry picked from commit 208ed3c)
…tenance

[Backport 2.33-maintenance] Windows fixes
Some filesystems, notably most FUSE-based ones and some top-level overlaysfs
ones do not support this and we need a graceful fallback.

(cherry picked from commit 06f2159)
…tenance

[Backport 2.33-maintenance] libutil: Gracefully fall back from unsupported O_TMPFILE
…ath infos

This was broken in 11d7c80.

(cherry picked from commit 2308f20)
…tenance

[Backport 2.33-maintenance] libstore/store-api: Do not query all substituters for substitutable p…
The previous error message was ambiguous about which specific directory failed the check.

This commit updates checkNotWorldWritable to return the failing path so it can be included in the error message, making debugging easier.

(cherry picked from commit a1e24fa)
…tenance

[Backport 2.33-maintenance] libstore: include path in the world-writable error
…tenance

[Backport 2.33-maintenance] Fix `curl` with `c-ares` failing to resolve DNS inside sandbox on macOS
Runs the tests against the new daemon as well as the cli.

This more reliably shares the artifact (not relying directly on github
actions cache). We've seen github evict our caches super fast, so it would
be nice to move away from it entirely if possible.

(cherry picked from commit 6eebfe6)
Also bumps download-artifact to v7.0.0.

(cherry picked from commit c54af23)
…tenance

[Backport 2.33-maintenance] ci: Run flake-regressions also with the newly built daemon
Best reviewed with -w --color-moved. This just moves the code
into a separate workflow. This will allow us to reuse it in
the release job for github releng of releases.

(cherry picked from commit 745983d)
This should allow reusing this workflow (with more tweaks)
in the releng workflow.

(cherry picked from commit c867ed6)
…tenance

[Backport 2.33-maintenance] ci: Move docker_push_image into a separate workflow
This allows for testing with a local minio deployment like:

./upload-release.pl --skip-docker --skip-git --s3-endpoint http://localhost:9000 --s3-host localhost:9000 1821360

(cherry picked from commit d19b8d5)
Previously it was only Eeclo doing releases that were signed with
B541D55301270E0BCF15CA5D8170B4726D7198DE. Other linux distributions
have the expectation (rightfully so) that our tags are signed. Let's
document this.

We could do cross-signing to make tracing the chain of trust easier
for all Nix team members [1].

[1]: https://nixos.org/community/teams/nix/

(cherry picked from commit 6cb8b58)
This workflow is supposed to automate release uploads by using OIDC
for AWS setup. DockerHub still uses long-lived credentials, but that's
not fixable. In a follow-up we could set up release uploads to GHCR too.

(cherry picked from commit 4599daa)
xokdvium and others added 9 commits January 1, 2026 14:45
…tenance

[Backport 2.33-maintenance] ci: GitHub releng for release automation
I messed up and accidentally configured the S3 client to use the same
host as the nix-releases bucket, but nix-channels is us-east-1 and
nix-releases is eu-west-1.

(cherry picked from commit 0900638)
…tenance

[Backport 2.33-maintenance] upload-release.pl: Fix up nix-channels bucket location, use awscli2
Previously builtins.readDir would return an empty attribute set
instead of barfing on non-existent paths. This is a regression from
2.32 for impure eval.

(cherry picked from commit 4ab2cda)
…tenance

[Backport 2.33-maintenance] libutil/union-source-accessor: Barf on non-existent directories
Tagging release 2.33.1
@coderabbitai
Copy link

coderabbitai bot commented Jan 16, 2026

📝 Walkthrough

Walkthrough

This PR performs a version bump to 2.33.1, reorganizes socket utility abstractions into a dedicated header, refactors the release process to use GitHub Actions workflows, removes the backport workflow, updates dev-shell dependencies with platform-conditional logic, improves anonymous temp file creation with O_TMPFILE optimization, adds error handling for missing directories in UnionSourceAccessor, and introduces comprehensive test coverage for readDir behavior on symlinks and non-existent paths.

Changes

Cohort / File(s) Summary
Version & Workflow Management
.github/workflows/backport.yml, .version
Removes entire backport GitHub Actions workflow (37 lines deleted); version bumped from 2.33.0 to 2.33.1
Maintainer Keys & Documentation
maintainers/keys/158A6F530EA202E5F651611314FAEA63448E1DF9.asc, maintainers/keys/B541D55301270E0BCF15CA5D8170B4726D7198DE.asc, maintainers/keys/README.md
Adds two PGP public key files (110 and 51 lines) and maintainer GPG keys documentation with fingerprints and TODO placeholders
Release Process & Scripts
maintainers/release-process.md, maintainers/upload-release.pl
Updates release documentation to use GitHub Actions workflow trigger (upload-release.yml) instead of manual script execution; refactors Perl uploader with new CLI options (skip-docker, skip-s3, skip-git, docker-owner, project-root) and conditional S3/Docker/Git operations (134 additions/88 deletions)
Development Environment
packaging/dev-shell.nix
Adds activeComponentNames and isActiveComponent helpers; applies platform-conditional logic for gdb and gbenchmark; filters nativeBuildInputs to exclude nix; adds Meson flags for kaitai-struct-checks and json-schema-checks
Derivation Builder
src/libstore/include/nix/store/build/derivation-builder.hh, src/libstore/unix/build/derivation-builder.cc, src/libstore/unix/build/sandbox-network.sb
Changes DerivationBuilderParams.initialOutputs from const reference to value; refactors checkNotWorldWritable from bool-returning to exception-throwing function; adds Mach lookup permission for SystemConfiguration.DNSConfiguration in sandbox
Store API
src/libstore/store-api.cc
Adds early loop break in querySubstitutablePathInfos after finding substitutable path info, preventing unnecessary substituter evaluations
Socket Abstraction Refactoring
src/libutil/include/nix/util/socket.hh (new), src/libutil/include/nix/util/unix-domain-socket.hh, src/libutil/include/nix/util/meson.build, src/libutil/serialise.cc, src/nix/unix/daemon.cc
Creates new socket.hh header with cross-platform Socket alias and toSocket/fromSocket converters; removes duplicate abstractions from unix-domain-socket.hh; updates serialise.cc and daemon.cc to use Socket wrappers in FD_SET/FD_ISSET operations
File System Utilities
src/libutil/file-system.cc
Optimizes createAnonymousTempFile to attempt O_TMPFILE with O_EXCL first, with static atomic memoization for unsupported filesystem; falls back to createTempFile on EOPNOTSUPP or EISDIR
Union Source Accessor
src/libutil/union-source-accessor.cc
Adds path existence tracking in readDirectory; throws FileNotFound when no underlying accessor contains the path, instead of returning empty listing
readDir Error Tests (Non-existent)
tests/functional/lang/eval-fail-readDir-nonexistent-{1,2}.{nix,err.exp}
Adds two test cases for readDir on non-existent absolute and relative paths with expected error output
readDir Error Tests (Non-directory)
tests/functional/lang/eval-fail-readDir-not-a-directory-{1,2}.{nix,err.exp}
Adds two test cases for readDir on regular files and symlinked non-directory targets with expected error output
readDir Success Tests (Symlinked)
tests/functional/lang/eval-okay-readDir-symlinked-directory.{nix,exp}
Adds test case for readDir on symlinked directory with expected output { git-hates-directories = "regular"; }

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~55 minutes

Possibly related PRs

  • PR #312: Modifies UnionSourceAccessor.readDirectory behavior for cache propagation alongside this PR's path existence validation changes
  • PR #261: Updates derivation builder codebase with function signature changes alongside this PR's DerivationBuilderParams member type adjustments

Suggested labels

flake-regression-test

Suggested reviewers

  • cole-h

Poem

🐰 Hopping through the code so fast,
Sockets bundled, classes recast!
Workflows gleam in Actions bright,
readDir tests now get it right!
Two-three-three-point-one, hop hooray!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Sync with upstream 2.33.1' clearly summarizes the main objective of the pull request, which is to synchronize code with upstream version 2.33.1, as evidenced by the version bump from 2.33.0 to 2.33.1 and the numerous upstream-related changes throughout the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.



📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c7047ac and 0fbf85f.

📒 Files selected for processing (1)
  • .github/workflows/backport.yml
💤 Files with no reviewable changes (1)
  • .github/workflows/backport.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build_x86_64-linux / build
  • GitHub Check: build_aarch64-darwin / build

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Jan 16, 2026

@github-actions github-actions bot temporarily deployed to pull request January 16, 2026 16:16 Inactive
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In @.github/workflows/backport.yml:
- Line 29: Update the backport action usage to either revert to the v3.x pin or
verify runner compatibility with v4.0.1: if keeping
korthout/backport-action@c656f5d5851037b2b38fb5db2691a03fa229e3b2 (v4.0.1),
ensure CI runners use Node.js 24 and GitHub Actions runner >= 2.327.1 and run a
full workflow test; alternatively pin to the last v3.x release to avoid Node 24
and runner requirements. Also review any commands calling execa in your
workflows or scripts and test them against the refactor to `@actions/exec` to
confirm behavior parity before merging.

In @.github/workflows/docker-push.yml:
- Around line 55-59: The install-nix-action step (uses:
./.github/actions/install-nix-action) is missing the required github_token
input; update that action invocation to include github_token: ${{
secrets.GITHUB_TOKEN }} alongside the existing inputs (dogfood and
extra_nix_config) so the action receives the mandatory token parameter.

In @.github/workflows/upload-release.yml:
- Around line 24-29: The workflow step using the local action install-nix-action
is missing the required github_token input; update the step that calls
install-nix-action to pass the repository token by adding the github_token input
(e.g., set github_token to the built-in secrets.GITHUB_TOKEN) alongside
dogfood/use_cache/extra_nix_config so the action’s required input is provided
when invoking install-nix-action.

In `@packaging/dev-shell.nix`:
- Around line 299-308: Fix the typo in the inline comment inside the dev shell
build expression: change the word "ross" to "cross" in the comment that explains
why we filter out "nix" from component nativeBuildInputs (the comment near the
expression using lib.filter, lib.lists.concatMap, and
activeComponents/nativeBuildInputs). Leave the surrounding logic untouched; only
correct the comment text to read "cross dev shell" instead of "ross dev shell".

In `@src/libstore/unix/build/derivation-builder.cc`:
- Around line 696-707: The error message in checkNotWorldWritable refers to
symlinks but the code only tests S_IWOTH; update the function to detect symlinks
using the lstat result (test S_ISLNK(st.st_mode)) and throw a clear error when
the path is a symlink or when it's world-writable (use separate messages or
include which condition triggered), keep the traversal via path.parent_path()
as-is, and remove the redundant final return; also ensure you call lstat
correctly and use the obtained struct stat (from lstat) when testing S_IWOTH and
S_ISLNK.
🧹 Nitpick comments (7)
maintainers/keys/README.md (1)

7-11: Consider adding an OpenPGP link for Eelco Dolstra's key for consistency.

Sergei Zimmerman's fingerprint is linked to keys.openpgp.org, while Eelco Dolstra's is not. Consider adding a similar link for consistency, which would also make it easier to verify and import the key.

Suggested change
 - **Eelco Dolstra**
-  GPG Fingerprint: `B541 D553 0127 0E0B CF15 CA5D 8170 B472 6D71 98DE`
+  GPG Fingerprint: [`B541 D553 0127 0E0B CF15 CA5D 8170 B472 6D71 98DE`](https://keys.openpgp.org/vks/v1/by-fingerprint/B541D55301270E0BCF15CA5D8170B4726D7198DE)
maintainers/upload-release.pl (2)

95-120: Potential issue with undefined s3_endpoint in regex match.

On line 105, $opt->s3_endpoint could be undefined when evaluating the regex =~ /^http:/. While Perl handles this gracefully (treats as empty string), it may generate a warning under use warnings. Consider adding an explicit check.

Similarly, lines 115-116 have redundant conditions—$opt->s3_endpoint ? (host => $opt->s3_host) sets host to s3_host only when s3_endpoint is provided, but this seems intentional for the channels bucket to use the default host unless a custom endpoint is specified.

♻️ Optional: Explicit check for s3_endpoint
-          secure                => ($opt->s3_endpoint && $opt->s3_endpoint =~ /^http:/) ? 0 : 1,
+          secure                => ($opt->s3_endpoint // '') =~ /^http:/ ? 0 : 1,

237-239: Missing semicolon after statement.

Line 238 is missing a trailing semicolon. While Perl tolerates this as the last statement in a block, it's better practice to include it for consistency and to avoid issues if code is added later.

♻️ Suggested fix
     $dockerManifest .= " --amend $tag";
-    $dockerManifestLatest .= " --amend $latestTag"
+    $dockerManifestLatest .= " --amend $latestTag";
 }
.github/workflows/upload-release.yml (1)

53-69: Redundant execution of upload-release.pl script.

The script is executed twice: once for S3/Docker Hub upload (lines 54-57) and once for GHCR (lines 63-67). Consider whether this could be consolidated into a single invocation with appropriate flags, or if the current separation is intentional for isolation purposes.

.github/workflows/docker-push.yml (2)

75-81: Quote shell variables to prevent word splitting.

Variables $NIX_VERSION and $DOCKERHUB_REPO should be quoted to prevent issues if they ever contain spaces or special characters.

♻️ Proposed fix
       run: |
-        docker tag nix:$NIX_VERSION $DOCKERHUB_REPO:$NIX_VERSION
-        docker push $DOCKERHUB_REPO:$NIX_VERSION
+        docker tag "nix:$NIX_VERSION" "$DOCKERHUB_REPO:$NIX_VERSION"
+        docker push "$DOCKERHUB_REPO:$NIX_VERSION"
         if [ "$IS_MASTER" = "true" ]; then
-          docker tag nix:$NIX_VERSION $DOCKERHUB_REPO:master
-          docker push $DOCKERHUB_REPO:master
+          docker tag "nix:$NIX_VERSION" "$DOCKERHUB_REPO:master"
+          docker push "$DOCKERHUB_REPO:master"
         fi

92-101: Quote shell variables consistently in GHCR push step.

Same quoting concern as the Docker Hub push step.

♻️ Proposed fix
       run: |
         IMAGE_ID=ghcr.io/${{ github.repository_owner }}/nix
         IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')

-        docker tag nix:$NIX_VERSION $IMAGE_ID:$NIX_VERSION
-        docker push $IMAGE_ID:$NIX_VERSION
+        docker tag "nix:$NIX_VERSION" "$IMAGE_ID:$NIX_VERSION"
+        docker push "$IMAGE_ID:$NIX_VERSION"
         if [ "$IS_MASTER" = "true" ]; then
-          docker tag nix:$NIX_VERSION $IMAGE_ID:master
-          docker push $IMAGE_ID:master
+          docker tag "nix:$NIX_VERSION" "$IMAGE_ID:master"
+          docker push "$IMAGE_ID:master"
         fi
src/libutil/include/nix/util/socket.hh (1)

17-56: Ensure Descriptor↔Socket casts are size-safe on Windows.

These reinterpret_casts assume Descriptor and Socket are the same width and that only socket-backed descriptors are passed on Windows. Please confirm the invariant; a compile-time guard would make the contract explicit.

♻️ Possible guard
 `#ifdef` _WIN32
+static_assert(sizeof(Descriptor) == sizeof(Socket),
+              "Descriptor and Socket must be the same size on Windows");
 /**
  * Windows gives this a different name
  */
 #  define SHUT_WR SD_SEND
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 322355f and c7047ac.

📒 Files selected for processing (31)
  • .github/workflows/backport.yml
  • .github/workflows/docker-push.yml
  • .github/workflows/upload-release.yml
  • .version
  • maintainers/keys/158A6F530EA202E5F651611314FAEA63448E1DF9.asc
  • maintainers/keys/B541D55301270E0BCF15CA5D8170B4726D7198DE.asc
  • maintainers/keys/README.md
  • maintainers/release-process.md
  • maintainers/upload-release.pl
  • packaging/dev-shell.nix
  • src/libstore/include/nix/store/build/derivation-builder.hh
  • src/libstore/store-api.cc
  • src/libstore/unix/build/derivation-builder.cc
  • src/libstore/unix/build/sandbox-network.sb
  • src/libutil/file-system.cc
  • src/libutil/include/nix/util/meson.build
  • src/libutil/include/nix/util/socket.hh
  • src/libutil/include/nix/util/unix-domain-socket.hh
  • src/libutil/serialise.cc
  • src/libutil/union-source-accessor.cc
  • src/nix/unix/daemon.cc
  • tests/functional/lang/eval-fail-readDir-nonexistent-1.err.exp
  • tests/functional/lang/eval-fail-readDir-nonexistent-1.nix
  • tests/functional/lang/eval-fail-readDir-nonexistent-2.err.exp
  • tests/functional/lang/eval-fail-readDir-nonexistent-2.nix
  • tests/functional/lang/eval-fail-readDir-not-a-directory-1.err.exp
  • tests/functional/lang/eval-fail-readDir-not-a-directory-1.nix
  • tests/functional/lang/eval-fail-readDir-not-a-directory-2.err.exp
  • tests/functional/lang/eval-fail-readDir-not-a-directory-2.nix
  • tests/functional/lang/eval-okay-readDir-symlinked-directory.exp
  • tests/functional/lang/eval-okay-readDir-symlinked-directory.nix
🧰 Additional context used
🧬 Code graph analysis (2)
src/nix/unix/daemon.cc (1)
src/libutil/include/nix/util/file-descriptor.hh (1)
  • getStandardInput (115-115)
src/libutil/union-source-accessor.cc (3)
src/libutil/include/nix/util/source-path.hh (1)
  • accessor (117-120)
src/libfetchers/include/nix/fetchers/filtering-source-accessor.hh (15)
  • path (35-35)
  • path (37-37)
  • path (39-39)
  • path (41-41)
  • path (43-43)
  • path (45-45)
  • path (47-47)
  • path (49-49)
  • path (51-51)
  • path (53-53)
  • path (55-55)
  • path (61-61)
  • path (66-66)
  • path (98-98)
  • path (100-100)
src/libfetchers/filtering-source-accessor.cc (3)
  • path (99-102)
  • showPath (59-62)
  • showPath (59-59)
🪛 actionlint (1.7.10)
.github/workflows/upload-release.yml

24-24: missing input "github_token" which is required by action "Install Nix" defined at "./.github/actions/install-nix-action". all required inputs are "dogfood", "github_token"

(action)

.github/workflows/docker-push.yml

55-55: missing input "github_token" which is required by action "Install Nix" defined at "./.github/actions/install-nix-action". all required inputs are "dogfood", "github_token"

(action)

🪛 Clang (14.0.6)
src/libutil/include/nix/util/socket.hh

[error] 4-4: 'nix/util/file-descriptor.hh' file not found

(clang-diagnostic-error)

🪛 markdownlint-cli2 (0.18.1)
maintainers/release-process.md

10-10: Bare URL used

(MD034, no-bare-urls)


110-110: Dollar signs used before commands without showing output

(MD014, commands-show-output)


183-183: Dollar signs used before commands without showing output

(MD014, commands-show-output)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build_x86_64-linux / build
  • GitHub Check: build_aarch64-darwin / build
🔇 Additional comments (39)
src/libstore/unix/build/sandbox-network.sb (1)

17-19: Scoped DNS permission looks appropriate.

This adds a narrowly targeted mach-lookup for DNS configuration, aligned with the DNS lookup allowance above.

tests/functional/lang/eval-okay-readDir-symlinked-directory.nix (1)

1-1: Test input looks good.

Simple, focused readDir invocation that matches the intended scenario.

tests/functional/lang/eval-okay-readDir-symlinked-directory.exp (1)

1-1: Expectation fixture is consistent.

Config flag aligns with the test case context.

tests/functional/lang/eval-fail-readDir-nonexistent-2.nix (1)

1-3: LGTM for eval-fail fixture.
Matches the intended non-existent relative path scenario and is minimal/clear.

tests/functional/lang/eval-fail-readDir-nonexistent-1.nix (1)

1-3: LGTM for eval-fail fixture.
Covers absolute-path non-existence case cleanly.

tests/functional/lang/eval-fail-readDir-nonexistent-1.err.exp (1)

1-16: Expected error output looks consistent.
Line/column pointers and final “does not exist” message align with the fixture.

tests/functional/lang/eval-fail-readDir-nonexistent-2.err.exp (1)

1-16: Expected error output looks consistent.
The resolved absolute path for the relative input is consistent with /pwd/lang.

src/libstore/store-api.cc (1)

452-463: Confirm substituter ordering before short‑circuiting.
Breaking after the first successful substituter changes selection semantics (first match now wins). Please verify getDefaultSubstituters() is deterministic and already ordered by desired priority; otherwise this could select a lower‑priority substituter compared to the previous “last match wins” behavior.

src/libutil/union-source-accessor.cc (1)

38-49: LGTM! Behavioral fix aligns with sibling methods.

The addition of the exists flag and the FileNotFound throw makes readDirectory consistent with readFile and readLink, which both throw when the path doesn't exist in any accessor. Previously, this method would silently return an empty DirEntries for non-existent paths, which could mask errors.

maintainers/keys/158A6F530EA202E5F651611314FAEA63448E1DF9.asc (1)

1-110: LGTM!

The PGP public key block is properly formatted with valid ASCII armor delimiters. The filename correctly corresponds to the GPG fingerprint, and the key identity matches Sergei Zimmerman as documented in the README.

maintainers/keys/B541D55301270E0BCF15CA5D8170B4726D7198DE.asc (1)

1-51: LGTM!

The PGP public key block is properly formatted with valid ASCII armor delimiters. The filename correctly corresponds to the GPG fingerprint, and the key identities match Eelco Dolstra as documented in the README.

tests/functional/lang/eval-fail-readDir-not-a-directory-1.nix (1)

1-3: LGTM!

This test correctly exercises the error path when builtins.readDir is called on a regular file rather than a directory. The test structure follows the standard eval-fail-* pattern and pairs properly with its .err.exp expectation file.

tests/functional/lang/eval-fail-readDir-not-a-directory-2.nix (1)

1-3: LGTM!

This test complements the first test by verifying error handling when readDir is applied to a symlink that resolves to a non-directory. The attribute name symlinkedRegularFile clearly documents the test scenario.

tests/functional/lang/eval-fail-readDir-not-a-directory-2.err.exp (1)

1-16: LGTM!

The expected error output correctly captures:

  • The evaluation trace through symlinkedRegularFile attribute
  • The readDir builtin call context with accurate line/column references
  • The resolved symlink target path in the final error message

The path difference between ./readDir/linked (input) and /pwd/lang/readDir/foo/git-hates-directories (error) correctly demonstrates that readDir follows symlinks before attempting to read the directory.

tests/functional/lang/eval-fail-readDir-not-a-directory-1.err.exp (1)

1-16: LGTM!

The expected error output properly documents the evaluation failure trace with accurate source locations. The error path /pwd/lang/readDir/bar directly corresponds to the test input ./readDir/bar, confirming this tests the direct regular-file case (vs. the symlink case in test 2).

src/libstore/include/nix/store/build/derivation-builder.hh (1)

82-82: Good fix for lifetime safety.

Changing initialOutputs from a const reference to by-value storage eliminates the risk of dangling references. This aligns with the PR's stated fix for heap-use-after-free in libstore. The constructor in derivation-builder.cc correctly moves DerivationBuilderParams, so the copy overhead is minimized.

src/libstore/unix/build/derivation-builder.cc (1)

728-729: LGTM!

The refactored call site is cleaner - exception-based error handling removes the need for explicit return value checks and is consistent with error handling patterns used elsewhere in this codebase.

src/libutil/file-system.cc (2)

735-737: LGTM!

Correct platform guard for Windows, where file deletion semantics while the file is open differ from Unix. On Windows, the temp file will be cleaned up when the process closes the descriptor or exits, rather than being immediately unlinked.


716-729: Well-designed graceful fallback for O_TMPFILE unsupported filesystems.

The implementation correctly:

  • Uses O_EXCL with O_TMPFILE to prevent accidental linking via linkat().
  • Handles both EOPNOTSUPP (POSIX) and EISDIR (historical Linux < 3.11 indicator) for proper fallback.
  • Uses std::atomic_flag for thread-safe memoization with benign race conditions.

The project uses C++23 as its standard, which fully supports std::atomic_flag::test() (C++20+ feature), so the code is compatible.

.version (1)

1-1: LGTM!

Version bump to 2.33.1 aligns with the PR objective to sync with upstream.

maintainers/release-process.md (2)

107-117: LGTM!

The updated release process now properly separates concerns: local tagging via upload-release.pl (with --skip-docker --skip-s3) followed by triggering the upload-release.yml workflow for artifact uploads. This provides a cleaner, more auditable release pipeline.


180-191: LGTM!

Point release documentation correctly mirrors the main release flow with the same workflow-driven approach.

packaging/dev-shell.nix (5)

151-158: LGTM!

Clean implementation of activeComponentNames and isActiveComponent for efficient O(1) membership testing. Using lib.listToAttrs to create a set-like lookup is idiomatic Nix.


202-214: LGTM!

The lib.intersectAttrs with lib.genAttrs pattern is a clean way to select a subset of components. This is more readable than the previous override approach.


282-293: LGTM!

Conditional Meson flags for kaitai-struct-checks and json-schema-checks based on active component membership is well-implemented.


325-325: LGTM!

Platform-specific inclusion of gdb only on Unix hosts is appropriate since gdb may not be available or functional on non-Unix platforms like Windows.


341-347: LGTM!

Conditional inclusion of gbenchmark on Unix platforms addresses the Windows build compatibility noted in the TODO comment.

maintainers/upload-release.pl (4)

17-40: LGTM!

Comprehensive CLI option parsing with Getopt::Long::Descriptive. The help text includes environment variables documentation, and the validation ensuring --project-root is required unless --skip-git is appropriate.


204-260: LGTM!

Docker handling is well-refactored:

  • Configurable docker_owner enables pushing to different registries
  • Multi-platform manifest creation is properly gated
  • The isLatest conditional correctly controls latest tag behavior

264-320: LGTM!

The S3 upload logic is properly gated by --skip-s3. The cross-platform tarball downloads are wrapped in eval/warn blocks for graceful degradation when builds aren't available. Content-type detection for uploads is appropriate.


323-329: LGTM!

Git tagging logic properly respects --skip-git and uses --force-with-lease for safer force-push of the latest-release branch.

.github/workflows/upload-release.yml (1)

1-69: Workflow structure looks reasonable.

The workflow appropriately:

  • Uses pinned action versions with SHA commits
  • Configures OIDC for AWS credentials
  • Sets minimal required permissions
  • Uses environment secrets for the releases environment
.github/workflows/docker-push.yml (2)

27-40: Good practice: secrets check before attempting push.

The check_secrets job pattern is a good approach to gracefully handle missing secrets in fork environments, avoiding workflow failures when secrets aren't configured.


42-48: Appropriate permission scoping.

The push job correctly requests only contents: read and packages: write permissions, following the principle of least privilege.

src/libutil/include/nix/util/meson.build (1)

69-69: LGTM — exporting socket.hh matches the new public API.

src/nix/unix/daemon.cc (1)

440-456: LGTM — Socket wrapper is applied consistently in the stdio forwarding loop.

src/libutil/include/nix/util/unix-domain-socket.hh (1)

4-7: LGTM — centralized socket helpers include.

src/libutil/serialise.cc (2)

1-5: LGTM — include aligns with the new socket abstraction.


184-200: LGTM — hasData() now uses the socket abstraction consistently.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +696 to 707
static void checkNotWorldWritable(std::filesystem::path path)
{
while (true) {
auto st = lstat(path);
if (st.st_mode & S_IWOTH)
return false;
throw Error("Path %s is world-writable or a symlink. That's not allowed for security.", path);
if (path == path.parent_path())
break;
path = path.parent_path();
}
return true;
return;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Error message mentions symlinks but code doesn't check for them.

The error message at line 701 states "Path %s is world-writable or a symlink", but the condition only checks S_IWOTH (world-writable bit). The symlink portion of the message appears to be outdated or incorrect.

Suggested fix
         if (st.st_mode & S_IWOTH)
-            throw Error("Path %s is world-writable or a symlink. That's not allowed for security.", path);
+            throw Error("Path %s is world-writable. That's not allowed for security.", path);

Also, the return; statement at line 706 is redundant at the end of a void function.

Optional cleanup
         path = path.parent_path();
     }
-    return;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
static void checkNotWorldWritable(std::filesystem::path path)
{
while (true) {
auto st = lstat(path);
if (st.st_mode & S_IWOTH)
return false;
throw Error("Path %s is world-writable or a symlink. That's not allowed for security.", path);
if (path == path.parent_path())
break;
path = path.parent_path();
}
return true;
return;
}
static void checkNotWorldWritable(std::filesystem::path path)
{
while (true) {
auto st = lstat(path);
if (st.st_mode & S_IWOTH)
throw Error("Path %s is world-writable. That's not allowed for security.", path);
if (path == path.parent_path())
break;
path = path.parent_path();
}
}
🤖 Prompt for AI Agents
In `@src/libstore/unix/build/derivation-builder.cc` around lines 696 - 707, The
error message in checkNotWorldWritable refers to symlinks but the code only
tests S_IWOTH; update the function to detect symlinks using the lstat result
(test S_ISLNK(st.st_mode)) and throw a clear error when the path is a symlink or
when it's world-writable (use separate messages or include which condition
triggered), keep the traversal via path.parent_path() as-is, and remove the
redundant final return; also ensure you call lstat correctly and use the
obtained struct stat (from lstat) when testing S_IWOTH and S_ISLNK.

@github-actions github-actions bot temporarily deployed to pull request January 16, 2026 19:18 Inactive
@edolstra edolstra added this pull request to the merge queue Jan 16, 2026
Merged via the queue into main with commit 2a57a00 Jan 16, 2026
28 checks passed
@edolstra edolstra deleted the sync-2.33.1 branch January 16, 2026 20:07
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.

9 participants