Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
fix: reclaim non-writable /tmp/gh-aw/sandbox before AWF writeConfigs() to prevent EACCES #42400
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
fix: reclaim non-writable /tmp/gh-aw/sandbox before AWF writeConfigs() to prevent EACCES #42400
Changes from all commits
63f87e81d71770File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[/diagnosing-bugs] The guard only checks
$sandbox_dir(/tmp/gh-aw/sandbox), but the same rootless-container residue can affect the parent/tmp/gh-aw. If/tmp/gh-awitself is root-owned,mkdir -p /tmp/gh-aw/agenton line 22 will fail with EACCES for exactly the same reason, bypassing this fix entirely.💡 Suggestion: extend the guard to the parent
Alternatively, just add an identical guard block for
gh_aw_dirbefore the sandbox one. The PR description focuses on the sandbox leaf, but the parent is exposed to the same rootless residue.@copilot please address this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stderr suppressed on
sudomay hide root-cause diagnostics.sudo rm -rf "${sandbox_dir}" 2>/dev/nulldiscards all stderr from sudo (permission denied, sudo not configured, PAM errors, etc.). If the removal fails, the caller only knows it failed — not why. Consider capturing stderr into the fallback warning so operators can diagnose the environment:Not blocking, but worth improving for debuggability in ephemeral runner environments.
@copilot please address this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[/diagnosing-bugs]
sudo rm -rf ... 2>/dev/nulldiscards all diagnostic context. If sudo is unconfigured (no NOPASSWD rule, passwordless sudo not available on the runner), the failure is invisible — only the generic WARN on the else branch surfaces, with no indication of why sudo failed.💡 Suggestion: capture and surface sudo's stderr
This keeps the happy path clean but threads sudo's error message through to the final WARN, making production triage immediate rather than requiring another run with manual debugging.
@copilot please address this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[/diagnosing-bugs]
sandbox_diris introduced for the guard but the subsequentmkdircalls use hardcoded strings. If the base path ever changes from/tmp/gh-aw, the guard and the mkdir calls drift silently.💡 One-line fix: derive paths from a shared variable
This is a minor but zero-cost DRY improvement that removes a future maintenance footgun.
@copilot please address this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Silent false-success on unrecoverable removal failure.
If both
sudo rm -rfandrm -rffail (theelsebranch on line 17–18), a[WARN]is emitted but the script keeps running. Because this script has noset -e, themkdir -phere fails withEACCESand exits silently — the script then reaches theechoon line 24 and exits0with a misleading success message. This recreates the exact outcome the PR is trying to prevent.Consider either exiting early in the
elsebranch, or addingset -eso the failingmkdirpropagates:@copilot please address this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sandbox_dirvariable defined but not used here — hardcoded path will silently drift if the variable ever changes.💡 Suggested fix
Line 10 defines
sandbox_dir="/tmp/gh-aw/sandbox"as a single source of truth, but line 23 hardcodes the same literal path:If
sandbox_diris ever updated (e.g. made configurable), the reclaim block picks up the new value but thismkdirstill targets the old path — silently recreating the stale root-owned tree that this PR is trying to fix. Use the variable consistently.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eval "${condition}"will silently misfire if a captured output variable contains single quotes or shell metacharacters.💡 Suggested fix
assertreceives a condition string like"echo '${OUTPUT}' | grep -q '...'". The caller expands${OUTPUT}at the call site, embedding it inside single quotes in the eval'd string. If the script output ever contains a'character (e.g. from a path likecan't write, or a future warning message), the heredoc-style quoting breaks and eval either throws a syntax error (silenced by2>/dev/null) or mis-parses the pipeline — causing a test to pass or fail spuriously with no indication of why.Replace the generic eval-based helper with direct assertions on pre-captured variables:
Or keep the helper but have callers pass a pre-evaluated boolean (exit code) rather than a string to eval.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[/tdd]
eval "${condition}"is fragile: if any assertion string contains a single quote (from script output, a path, or an error message), the eval'd condition breaks silently — the assertion counts as failed but gives no diagnostic hint.💡 Suggestion: use a dedicated output assertion helper
Keeping file/output assertions separate from the generic
eval-based helper eliminates the quoting hazard and also improves failure messages (the needle is printed, not just "assertion failed").@copilot please address this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[/tdd] Test 2 says "from scratch" but doesn't ensure
/tmp/gh-awis clean first. If run after Test 1 (which runs the script) or in an already-provisioned environment,/tmp/gh-aw/sandbox/agent/logsalready exists — the test passes vacuously rather than verifying directory creation. Tests 3 and 4 also leave state that bleeds into subsequent runs.💡 Suggestion: add a trap cleanup and a per-test reset
This makes the test description match the actual precondition and ensures re-runs (e.g.,
bash create_gh_aw_tmp_dir_test.shrun twice in a row) stay deterministic.@copilot please address this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests mutate the real
/tmp/gh-aw/sandboxpath without isolation — running this test suite while an AWF job is live will corrupt the active sandbox.💡 Suggested fix
Tests 2–4 all operate directly on
/tmp/gh-aw/sandbox. If these tests are ever run on a shared or self-hosted runner that has a live AWF session, thechmod 555,rm -rf, andmkdir -pcalls will race against AWF writes.The script should accept a configurable base path so the tests can redirect to a throw-away directory:
This also eliminates the need for a separate EXIT trap because the mktemp dir is always cleaned up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
evalinassert()is fragile with paths that contain special characters.Conditions are constructed by interpolating shell variables (e.g.
${SUDO_ARGS_FILE},${MARKER_FILE}) into strings and theneval-ing them. If a temp-dir path frommktemp -dhappens to contain whitespace or glob characters, assertions can silently mismatch or expand unexpectedly.Prefer using a function that accepts a command and its arguments as separate parameters — this avoids
evalentirely:@copilot please address this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[/tdd] The
elsebranch (when bothsudoand plainrm -rffail) has no test. This is the most safety-critical path — the script emits a WARN and exits 0, silently allowing AWF to proceed and hit the original EACCES. Without coverage here, a future change to the warning text or exit logic has no regression guard.💡 Suggested Test 5 skeleton
Covering this path ensures the diagnostic warning message is never accidentally dropped.
@copilot please address this.
Uh oh!
There was an error while loading. Please reload this page.