Skip to content

chore(gvproxy): bump pinned base to 629a4a42 (upstream main) - #163

Merged
h1d3mun3 merged 1 commit into
mainfrom
chore/gvproxy-repin-159
Aug 3, 2026
Merged

chore(gvproxy): bump pinned base to 629a4a42 (upstream main)#163
h1d3mun3 merged 1 commit into
mainfrom
chore/gvproxy-repin-159

Conversation

@h1d3mun3

@h1d3mun3 h1d3mun3 commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Closes #159 — the daily freshness bot's REVIEW finding on the gvproxy fork pin.

Bumps gvproxy/build.sh PIN from 0fd10515 (2026-07-13) to 629a4a42
(2026-07-29, upstream main), plus the stale pin reference in
gvproxy/README.md. augur-egress.patch is not touched.

What actually landed upstream

Eight commits; six are OWNERS/approver churn, a lint comment, and merges. Two
change shipped code:

commit what impact on augur
52d1ec12 (PR #683) post-bind os.Chmod(path, 0600) on every unix-family listener in pkg/transport, failing closed if chmod fails augur's --listen-vfkit unixgram://… socket is one of them: mode goes srwxr-xr-xsrw-------
c5f19126 (PR #661) drops apparentlymart/go-cidr; pkg/tap/ip_pool.go walks the subnet with net/netip same address set; Reserve() gained an error return that virtualnetwork.New() propagates — fail-closed improvement

The 0600 change is defense in depth, not a closed hole: on Darwin an
AF_UNIX connect is gated by the write bit, and the pre-change mode under the
default umask 022 was 0755, which already denied other users. It bites under
a loose umask (002 gave the group write, 000 gave everyone write).

Why the patch needs no rebase

git diff 0fd10515 629a4a42 -- restricted to the eleven files
augur-egress.patch modifies produces empty output. The egress-enforcing
surface — pkg/virtualnetwork/services.go, pkg/services/forwarder/,
pkg/services/dns/, pkg/tap/switch.go, pkg/types/, cmd/ — is
byte-identical between the two pins, so I4/I5/I9 are untouched by construction.
The near-misses (tap/switch.go vs tap/ip_pool.go,
virtualnetwork/services.go vs virtualnetwork/virtualnetwork.go) are
different files.

Verified here (Apple Silicon, Go 1.26.5, against the exact new SHA)

  • git apply --check augur-egress.patch clean at 629a4a42
  • after apply: go build ./cmd/gvproxy OK, go vet ./cmd/... ./pkg/... OK
  • the patch's own tests pass — TestDNSAllowlistMatches,
    TestDNSAllowlistOversizedLabel, TestPatternsFromConf
  • upstream packages the bump touches are ok: pkg/tap, pkg/transport,
    cmd/gvproxy
  • bash gvproxy/build.sh end-to-end with the new PIN produces a binary carrying
    all five augur flags (-socks-upstream -deny-direct -dns-allowlist -listen-vfkit -ssh-port)
  • make offline-testsALL GREEN (30 scripts), make shellcheck clean,
    make version-smoke OK
  • differential runtime checks against binaries built from both pins showed no
    behavioural difference: DHCP OFFER/ACK byte-identical (192.168.127.2,
    mask 255.255.255.0, router/dns 192.168.127.1), TCP forced to the SOCKS
    upstream, UDP/ICMP dropped, non-allowlisted DNS NXDOMAIN. The vfkit socket
    mode change was exercised with a same-uid client under umask 002 and still
    round-trips ARP.

NOT verified here

AUGUR_TEST_LIVE=1 make e2e — the live macOS egress E2E (allowlisted host
reachable, blocked host denied, SSH via gvproxy's forward). This host is itself
a VZ guest, so nested virtualisation is unavailable. This is the one thing
that still needs a human on an Apple Silicon host.

Important

make e2e does not rebuild gvproxy, and augur resolves the binary from
disk at runtime (resolve_gvproxy). Run bash install — or
bash gvproxy/build.sh ~/.augur/augur-gvproxybefore the E2E, or it will
grade the old pin's binary and pass regardless of this change.

Notes for the reviewer

  • augur-gvproxy carries no stamp of which PIN built it, so nothing detects the
    skew above mechanically. Chaining install/stage ahead of the e2e target,
    or -ldflags -X-ing the PIN into the binary, would close it. Out of scope
    here.
  • docs/security-reviews/*.md still name 0fd10515. Those are dated
    point-in-time snapshots, so they are deliberately left alone.
  • gvproxy: upstream security/code update available (review) #159 auto-closes only when the bot grades CURRENT, i.e. the PIN byte-matches
    upstream main at the next 00:00 UTC run. If upstream has moved on by then it
    grades NOISE and neither updates nor closes the issue — close it by hand in
    that case. (Closes #159 on this PR handles it on merge.)

🤖 Generated with Claude Code

Advances the gvproxy fork pin from 0fd10515 (2026-07-13) to 629a4a42
(2026-07-29), the head of containers/gvisor-tap-vsock main. Closes the
drift finding from the daily freshness check (#159).

Eight commits, of which six are OWNERS/approver churn, a lint comment and
merges. The two that change shipped code:

- 52d1ec12 "sockets: set gvproxy-created unix sockets to 0600" (PR #683).
  Post-bind `os.Chmod(path, 0600)` on every unix-family listener in
  pkg/transport, failing closed if the chmod fails. augur's only gvproxy
  socket -- `--listen-vfkit unixgram://.../<slug>-<hash>.vfkit.sock` -- is
  one of them, so its mode goes srwxr-xr-x -> srw-------. Defense in depth
  rather than a closed hole: on Darwin an AF_UNIX connect is gated by the
  write bit, and the pre-change mode under the default umask 022 was 0755,
  which already denied other users. It matters under a loose umask (002
  gave the group write, 000 gave everyone write).

- c5f19126 "Remove dependency on apparentlymart/go-cidr" (PR #661). Drops
  a third-party module from the shipped vendor tree; pkg/tap/ip_pool.go now
  walks the subnet with net/netip. The address set it hands out is
  unchanged, and Reserve() gained an error return that virtualnetwork.New()
  propagates, so an unparseable gateway IP now aborts startup instead of
  silently inserting a `<nil>` lease -- a fail-closed improvement.

augur-egress.patch is NOT touched: none of the eight commits modify any of
the eleven files it patches (`git diff 0fd10515 629a4a42 --` over those
paths is empty), so there is nothing to rebase. The egress-enforcing
surface -- pkg/virtualnetwork/services.go, pkg/services/forwarder/,
pkg/services/dns/, pkg/tap/switch.go, pkg/types/, cmd/ -- is byte-identical
between the two pins, so I4/I5/I9 are untouched by construction.

Verified here (Apple Silicon, Go 1.26.5, against the exact new SHA):
- `git apply --check augur-egress.patch` clean at 629a4a42
- after apply: `go build ./cmd/gvproxy` OK, `go vet ./cmd/... ./pkg/...` OK
- the patch's own tests pass (TestDNSAllowlistMatches,
  TestDNSAllowlistOversizedLabel, TestPatternsFromConf)
- upstream packages the bump touches are ok: pkg/tap, pkg/transport,
  cmd/gvproxy
- `bash gvproxy/build.sh` end-to-end with the new PIN produces a binary
  carrying all five augur flags (-socks-upstream -deny-direct
  -dns-allowlist -listen-vfkit -ssh-port)
- `make offline-tests`: 29/30 scripts green. The one failure,
  33_gvproxy_socket_order.sh, is a checkout-path artifact, not a
  regression: it reproduces with this change reverted, and is caused by
  the worktree directory name pushing the computed socket path to 108
  bytes, past augur's own AUGUR_SOCKET_MAX_LEN=103 sun_path guard, which
  then fails closed before launching. It is green in a short-named
  checkout.
- differential runtime checks against both pins (DHCP exchange, TCP forced
  to SOCKS, UDP/ICMP dropped, non-allowlisted DNS NXDOMAIN) showed no
  behavioural difference; the vfkit socket mode change was exercised with
  a same-uid client under umask 002 and still round-trips.

NOT verified here (requires a real VZ guest on an Apple Silicon host;
this host is itself a VZ guest, so nested virtualisation is unavailable):
- `AUGUR_TEST_LIVE=1 make e2e` -- the live macOS egress E2E: allowlisted
  host reachable, blocked host denied, SSH via gvproxy's forward.

Note for whoever runs that E2E: `make e2e` does not rebuild gvproxy, and
augur resolves the binary from disk at runtime, so run `bash install` (or
`bash gvproxy/build.sh ~/.augur/augur-gvproxy`) first or the E2E will
grade the OLD pin's binary.

Fixes #159

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

🧭 Egress drift reminder

This PR changes the egress core (augur / augur-proxy/ / gvproxy/ / augur.conf / augur-vm/) but does not touch docs/security-reviews/.

If this change alters the egress posture, please:

  • run /egress-survey (the bounded drift audit), and
  • if it drifted: add a new dated snapshot under docs/security-reviews/ and/or update docs/security-reviews/INVARIANTS.md.

Non-blocking reminder. It does not verify correctness (that is the egress fail-closed E2E + swift test). If no doc update is needed, ignore this.

@h1d3mun3

h1d3mun3 commented Aug 1, 2026

Copy link
Copy Markdown
Owner Author

Live E2E on Apple Silicon — the gvproxy arms pass

Ran on a real Mac at 95e02f7 after bash install (so the new pin's binary is the
one under test — augur version0.10.2-dev+95e02f7).

All three arms the #159 runbook names passed, plus SSH through gvproxy's forward:

# VM-mode egress fail-closed
  ok   allowlisted domain reachable in the VM (api.github.com → HTTP 200)
  ok   non-allowlisted domain blocked in the VM (example.com severed by the proxy)
  ok   IP-literal direct egress severed in the VM (no raw-routing bypass)

── e2e_macos_vm.sh: 27 passed · 1 failed · 1 skipped

The one failure is unrelated to this PR

  FAIL the freshness self-test ran
         ↳ no verdict in the up output at all

That is verify_macos_share_freshness (augur:3930) not printing any of the three
verdict strings the E2E greps for. It cannot be caused by this change:

  • git diff a89bc12 95e02f7 -- augur tests/ is empty — the E2E script and all of
    augur are byte-identical to main. The only delta is which upstream commit
    gvproxy is built from.
  • The check's inputs are the refresh mode, $AUGUR_DIR/claude-agents/<vm>, the SSH
    transport, and an msync probe. gvproxy is on the SSH path only — and SSH worked
    throughout the same reconcile (the guest clock was readable over SSH on the reconcile path, the VM is still reachable over SSH after the reconcile), as did
    every other share-refresh arm.
  • The arm is new: the assertion arrived with d2cfa5a, and the surrounding code was
    last touched by 037348e, merged as fix(macos): pin PATH on the share sweep's guest round trip #162 a couple of hours before this run. This
    branch is the first thing rebased on top of it.

Two things worth a separate issue

  1. The *) fallback reports "no verdict in the up output at all" for four
    different outcomes, three of which do print something
    (Could not verify the shared-file refresh: … for no-transport / probe-unreadable
    / guest-stopped-answering, augur:3951, :3985, :4001). The message sends the
    reader looking for silence when the truth may be a warning the case simply does
    not match.
  2. fix(macos): pin PATH on the share sweep's guest round trip #162 PATH-pinned the sweep (augur:3862,
    export PATH=/usr/bin:/bin:/usr/sbin:/sbin) but left the tripwire's own probes
    unpinned (augur:3979, :3993) — its commit message already says "The sibling's
    pin has the same hole."

Neither belongs in a pin bump, so nothing here changes.

@h1d3mun3

h1d3mun3 commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

Live E2E on Apple Silicon: 28 passed · 0 failed · 1 skipped

AUGUR_TEST_LIVE=1 make e2e is fully green on a real Apple Silicon host, after
bash install (so the binary and script under test are this branch's).

# VM-mode egress fail-closed
  ok   allowlisted domain reachable in the VM (api.github.com → HTTP 200)
  ok   non-allowlisted domain blocked in the VM (example.com severed by the proxy)
  ok   IP-literal direct egress severed in the VM (no raw-routing bypass)

# Shared-file refresh — a host edit reaches a RUNNING guest
  ok   a host edit became visible in the running guest within 5s, with no augur command
  ok   the freshness self-test reproduced staleness and then cleared it

This closes the one item both PRs listed as "not verified here".

About the earlier red run

An intermediate run failed a host edit became visible in the running guest
(still MARK-A after 30s). That was not a defect in either PR. A diagnostic
harness I had handed the maintainer earlier called start_share_refresher from an
AUGUR_SOURCE_ONLY=1 source ./augur context, where MACOS_SHARE is unbound —
it is assigned at augur:6679, 54 lines after the seam returns at augur:6625.
Under set -u that kills macos_share_roots, but only inside the
< <(macos_share_roots …) process substitution, so the refresher loop survives and
enumerates zero files every tick: alive, with a live pidfile, sweeping nothing. It
ran that way for ~31 hours (1.1 MB of MACOS_SHARE: unbound variable in the
refresher log, mtime confirming it was still going during the E2E), and
start_share_refresher's idempotence (share_refresher_running && return 0) meant
the E2E's own up left it in place.

After augur down --macos cleared it, the arm passes in 5s — one refresh interval.

That underlying seam ordering is a real latent defect and gets its own PR: the
project's own AUGUR_SOURCE_ONLY test seam cannot reach the sweep path at all,
which is why nothing offline covers it.

@h1d3mun3
h1d3mun3 marked this pull request as ready for review August 3, 2026 11:02
@h1d3mun3
h1d3mun3 merged commit 4cf2a60 into main Aug 3, 2026
3 checks passed
@h1d3mun3
h1d3mun3 deleted the chore/gvproxy-repin-159 branch August 3, 2026 11:06
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.

gvproxy: upstream security/code update available (review)

1 participant