Skip to content

uphold 1.14.1: the shim cannot spawn itself - #135

Merged
HackingGate merged 1 commit into
mainfrom
release-1.14.1
Sep 2, 2026
Merged

uphold 1.14.1: the shim cannot spawn itself#135
HackingGate merged 1 commit into
mainfrom
release-1.14.1

Conversation

@HackingGate

Copy link
Copy Markdown
Owner

Point the documented pins at 1.14.1 and bump the crate version: Cargo.toml,
Cargo.lock, README.md, hooks/lefthook.yml.

Why a patch

No name a policy can write changes, and no seam starts refusing anything it
allowed at 1.14.0. A consumer who bumps a rev or a ref gets a binary that
answers its own questions without asking itself.

The single change since 1.14.0 is #134, which closes #133. On 2026-09-02 a
git push inside this repository's own checkout, under the released v1.13.0
binary, spawned roughly 250 processes a second and drove the load average past
3000; nothing short of kill -9 -<pgid> stopped it. The shim answers a
public-target scope by running gh api repos/<owner>/<repo>, PATH resolves
that gh to the shim, and the tree's policy had grown an api:* match entry
that the probe's own argv hits. So v1.13.0 fork-bombs a workstation whenever
its policy gains a match entry a probe's argv hits.

v1.14.0 removed one trigger, by exempting a bodyless GET. It did not remove the
mechanism: any other new match entry, or a binary and a policy that disagree
about which entries exist, reopens it, and Target::GitRemote had the same
exposure through git remote get-url origin with no exemption in front of it
at all.

#134 removes the mechanism. Every internal spawn of git, gh or glab from
the decision path goes through shim::inner_tool, which marks the child with
UPHOLD_SHIM_INNER=<depth>; the entry point, seeing the marker, resolves the
real tool through the PATH walk that already skips its own file and hands over
without judging, before the working directory and before the policy. The value
counts rather than flags, so past depth 2 the seam refuses with exit 2 and
names the loop: a regression in the passthrough is bounded by a refusal rather
than by the machine.

Verification

cargo build, cargo test (762 pass, 0 fail), cargo clippy --all-targets,
cargo fmt --check and prek run --all-files --hook-stage manual are all
clean on this branch.

https://claude.ai/code/session_01HEudouCNhFHK6UPEWcWqXd

Point the documented pins at 1.14.1 and bump the crate version.

Patch, not minor. No name a policy can write changes. The one change since
1.14.0 is #134, which closes the loop reported in #133: on 2026-09-02 a
git push inside this repository's own checkout, under the released v1.13.0
binary, spawned roughly 250 processes a second and drove the load average
past 3000, because the shim's own public-target probe resolved gh through
PATH to itself and the tree's policy had grown a match entry that probe's
argv hit.

1.14.0 removed one trigger by exempting the bodyless GET. This removes the
mechanism: every internal spawn of git, gh or glab from the decision path
carries UPHOLD_SHIM_INNER, and the entry point seeing that marker resolves
the real tool and hands over without judging. The value counts, so a
regression in that passthrough is bounded by a refusal at depth rather than
by the machine.

Landed in this release: #134.

A policy written against 1.14.0 loads unchanged, and a consumer who bumps a
rev or a ref gets no new refusal. The marker is documented beside
UPHOLD_ALLOW because exported by hand it is that variable under another
name, and it prints the same unchecked notice on stderr.

Claude-Session: https://claude.ai/code/session_01HEudouCNhFHK6UPEWcWqXd
@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 45 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 5f12a44c-8034-4c4d-8800-5ab8b48e9cfe

📥 Commits

Reviewing files that changed from the base of the PR and between 66537e5 and 7c5665f.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • Cargo.toml
  • README.md
  • hooks/lefthook.yml

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.41%. Comparing base (66537e5) to head (7c5665f).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #135   +/-   ##
=======================================
  Coverage   93.41%   93.41%           
=======================================
  Files          38       38           
  Lines       14443    14443           
=======================================
  Hits        13492    13492           
  Misses        951      951           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@HackingGate
HackingGate merged commit 57b3554 into main Sep 2, 2026
12 checks passed
@HackingGate
HackingGate deleted the release-1.14.1 branch September 2, 2026 13:14
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.

The shim resolves its own probes through PATH, so a match entry can make it call itself without bound

2 participants