Skip to content

dag: normalize modRoot to fix -trimpath leak when subPackages=["."]#129

Merged
Mic92 merged 1 commit intomainfrom
aldo/fix-trimpath-modroot-leak
Apr 23, 2026
Merged

dag: normalize modRoot to fix -trimpath leak when subPackages=["."]#129
Mic92 merged 1 commit intomainfrom
aldo/fix-trimpath-modroot-leak

Conversation

@aldoborrero
Copy link
Copy Markdown
Member

Summary

When modRoot = "./foo" and the main package is at the module root (subPackages = ["."], the default), moduleRoot = "${mainSrc}/${modRoot}" produces …-main-src/./foo. linkbinary.go passes that as srcdir for the sp.Path == "." branch; compile.go:88 builds the -trimpath rewrite key from it; runIn sets cwd to the same dirty path but the kernel canonicalizes; the compiler records the clean path; cmd/internal/objabi's prefix match misses; mainSrc lands in pclntab and the binary's closure references the source tree.

subPackages = ["./cmd/…"] never hit this — that branch goes through filepath.Join(m.ModuleRoot, clean), which normalizes.

Changes

  • nix/dag/default.nix — hoist cleanModRoot to the top-level let; use it in moduleRoot
  • linkbinary.gofilepath.Clean(m.ModuleRoot) for the sp.Path == "." branch (covers any other unnormalized source of ModuleRoot)
  • nix/dag/default.nix — add mainSrc to disallowedReferences so future leaks fail at build time instead of silently bloating the closure
  • tests/fixtures/modroot-dotslash/ + tests/nix/modroot_dotslash_test.nix — regression fixture (modRoot = "./app", default subPackages); the disallowedReferences guard fails the build if the leak recurs, and the test additionally checks nix-store -q --references and runs the binary

Reproduction

$ nix-build tests/fixtures/modroot-dotslash/dag.nix  # before this PR
$ nix-store -q --references ./result
/nix/store/…-modroot-dotslash-main-src   # ← source tree in closure

When modRoot = "./foo" and the main package is at the module root,
moduleRoot = "${mainSrc}/${modRoot}" produces …-main-src/./foo.
linkbinary.go passes that as srcdir; compile.go builds the -trimpath
rewrite key from it; the compiler records the kernel-canonicalized
clean cwd; objabi's prefix match fails and mainSrc lands in pclntab.

subPackages = ["./cmd/…"] never hit this — that branch goes through
filepath.Join, which normalizes.

- Hoist cleanModRoot to top-level let; use it in moduleRoot.
- linkbinary.go: filepath.Clean(m.ModuleRoot) for the sp.Path == "."
  branch (defense in depth — covers any other unnormalized source).
- Add mainSrc to disallowedReferences so future leaks fail at build
  time instead of silently bloating the closure.
- Regression fixture (modroot-dotslash) + flake check that builds it.
@aldoborrero aldoborrero force-pushed the aldo/fix-trimpath-modroot-leak branch from 1e45c4d to d73c581 Compare April 22, 2026 20:20
@aldoborrero aldoborrero requested a review from Mic92 April 22, 2026 20:28
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 22, 2026

Benchmark Regression Check

Scenario Tool Base (s) Current (s) Change Drvs (base) Drvs (curr) Status
no_change nix-ca-nocgo 0.66 0.69 +4.8% 0 0 ok
no_change nix-nocgo 0.67 0.69 +2.7% 0 0 ok
leaf-private nix-ca-nocgo 2.56 2.59 +1.4% 2 2 ok
leaf-private nix-nocgo 1.67 1.76 +5.2% 2 2 ok
mid-private nix-ca-nocgo 2.67 2.83 +6.0% 2 2 ok
mid-private nix-nocgo 1.93 1.86 -3.6% 4 4 ok
deep-private nix-ca-nocgo 3.31 3.41 +3.0% 3 3 ok
deep-private nix-nocgo 2.11 2.15 +1.9% 8 8 ok

Baseline: main | Current: 0dd86aa7b8600409730156ee378cd2a7ac9421f4

@Mic92 Mic92 added this pull request to the merge queue Apr 23, 2026
Merged via the queue into main with commit 1c3cd44 Apr 23, 2026
3 of 4 checks passed
@Mic92 Mic92 deleted the aldo/fix-trimpath-modroot-leak branch April 23, 2026 11:08
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