Skip to content

feat(find): add --help, -type b/c, -perm, -quit; fix access TOCTOU#104

Merged
matt-dz merged 43 commits intomainfrom
find-help-and-type-bc
Mar 18, 2026
Merged

feat(find): add --help, -type b/c, -perm, -quit; fix access TOCTOU#104
matt-dz merged 43 commits intomainfrom
find-help-and-type-bc

Conversation

@matt-dz
Copy link
Copy Markdown
Collaborator

@matt-dz matt-dz commented Mar 16, 2026

Summary

  • find --help — standalone --help flag triggers usage output, including when it appears after path operands
  • find -type b,c — block and character device matching via comma-separated type lists
  • find -perm MODE — full octal and GNU symbolic mode support (u=rwx,g=rx, copy-bits g=u, conditional execute X, setuid/setgid/sticky s/t, all three operators =/+/-)
  • find -quit — immediate exit action; no longer suppresses implicit -print (matches GNU find)
  • Remove -readable — non-POSIX GNU extension with root-dependent behavior; use -perm instead
  • Fix access TOCTOU — open-first with O_NONBLOCK for single-inode permission checks; eliminates Stat→OpenFile double resolution
  • Fix Windows -x — always deny execute checks on Windows (no POSIX execute bits)
  • Fix compliance — add golang.org/x/sys to LICENSE-3rdparty.csv
  • Clean up stale tests — remove redundant/root-sensitive scenarios (test_exec_check, test_write_denied, readable_*)

Test plan

  • go test ./... -count=1 -timeout 120s — full suite passes
  • RSHELL_BASH_TEST=1 go test ./tests/ -run TestShellScenariosAgainstBash -timeout 120s — GNU find parity verified for -quit implicit-print behavior
  • GOOS=windows go build ./... — cross-compiles cleanly
  • go test ./allowedsymbols/ -run TestAllowedSymbols -count=1 — symbol allowlist passes
  • RSHELL_COMPLIANCE_TEST=1 go test ./tests/ -run TestCompliance -v — compliance passes
  • gofmt -l . — clean

🤖 Generated with Claude Code

@matt-dz matt-dz changed the title feat(find): add --help flag and -type b,c support feat(find): add --help, -type b/c, and 21 GNU find predicates Mar 16, 2026
Copy link
Copy Markdown
Collaborator Author

@matt-dz matt-dz left a comment

Choose a reason for hiding this comment

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

Self-Review — Iteration 1

Overall assessment: needs minor fixes (no P0, 1×P1, 3×P2, 1×P3)

This is a well-structured PR that adds 21 GNU find predicates with proper platform-specific stat helpers, sandbox-safe imports, and good test coverage. The core architecture (expr/eval/match separation, iterative stack-based walk) is maintained cleanly. All new predicates go through the sandbox's CallContext interface — no direct filesystem access.

Summary Table

# Priority File Finding
1 P1 eval_predicates.go:152-179 -samefile re-stats reference file on every entry (O(N) stat amplification)
2 P2 eval_predicates.go:88-98 -user/-group error for unknown names printed on every file visit
3 P2 eval_predicates.go:228-232 -ls uses 1K blocks; GNU find uses 512-byte blocks
4 P2 eval_predicates.go -printf missing commonly used directives %P, %H, %k
5 P3 expr.go:640 goto doneWho in parseSymbolicMode is non-idiomatic Go

Positive Observations

  • All filesystem access goes through CallContext (sandbox-safe)
  • -readable/-writable/-executable correctly use AccessFile — no raw os.Access
  • -perm parsing handles octal and symbolic modes with proper validation
  • -quit propagation through AND/OR/NOT is correct
  • -depth post-order traversal handles starting dir correctly via isStartDir flag
  • Platform-specific files use proper build tags
  • Overflow protection constants follow the maxMtimeN/maxMminN pattern
  • evalTimeInDays/evalTimeInMinutes correctly extract shared logic

Comment thread builtins/find/eval_predicates.go Outdated
Comment thread builtins/find/eval_predicates.go Outdated
Comment thread builtins/find/eval_predicates.go Outdated
Comment thread builtins/find/eval_predicates.go Outdated
Comment thread builtins/find/expr.go Outdated
@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Mar 16, 2026

@codex review this PR

Important: Read the SPECS section of the PR description. If SPECS are present: make sure the implementation matches ALL the specs.
The specs override other instructions (code, inline comments in code, etc). ALL specs MUST be implemented.

@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Mar 16, 2026

Iteration 1 self-review result: COMMENT — 5 findings (1×P1, 3×P2, 1×P3). Key issues: -samefile O(N) stat amplification (P1), -user/-group error spam (P2), -ls block size mismatch (P2), -printf missing directives (P2).

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 516aed27f2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread builtins/find/expr.go Outdated
Comment thread builtins/find/expr.go
Comment thread builtins/find/eval_predicates.go Outdated
Comment thread builtins/find/eval.go
@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Mar 16, 2026

@codex review this PR

Important: Read the SPECS section of the PR description. If SPECS are present: make sure the implementation matches ALL the specs.
The specs override other instructions (code, inline comments in code, etc). ALL specs MUST be implemented.

Copy link
Copy Markdown
Collaborator Author

@matt-dz matt-dz left a comment

Choose a reason for hiding this comment

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

Self-Review — Iteration 2

APPROVE (no findings) — all 5 findings from iteration 1 addressed. Caches are per-walk (no cross-invocation leaks). Windows tests fixed with stdout_windows.

@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Mar 16, 2026

Iteration 2 self-review result: APPROVE (no findings) — all iteration 1 findings addressed. No new issues introduced by the fixes.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5531bf1376

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread builtins/find/expr.go Outdated
Comment thread builtins/find/eval_predicates.go Outdated
Comment thread builtins/find/eval_predicates.go Outdated
@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Mar 16, 2026

Review-Fix Loop Summary

Iteration log

# Review result Findings Fixes applied CI status
1 COMMENT 5 (1×P1, 3×P2, 1×P3) 5 fixed + 4 Windows test fixes Passing (except flaky fuzz)
2 APPROVE 0 (self) + 4 codex (4×P1) 3 fixed, 1 deferred (-daystart positional) Passing
3 APPROVE 0 (self) + 3 codex (stale, already fixed) 0 (all pre-addressed) Passing

Final state

  • Self-review: APPROVE (no findings)
  • Unresolved external comments: 0
  • CI: All checks passing

Fixes applied across all iterations

  1. P1: -samefile O(N) stat amplification → cached via samefileCache on evalContext
  2. P1: -quit not treated as action → added to isAction()
  3. P1: -user/-group unknown name not fatal → added eager validation in run()
  4. P1: -perm drops setuid/setgid/sticky bits → use full Mode() instead of Perm()
  5. P2: -user/-group error printed per-file → cached via userCache/groupCache
  6. P2: -ls uses 1K blocks → fixed to 512-byte blocks (GNU find compat)
  7. P2: -printf missing %P, %H, %k → implemented with startPath on evalContext
  8. P3: goto doneWho → replaced with labeled break whoLoop
  9. Platform: Windows perm/executable tests → added stdout_windows assertions

Deferred to follow-up

  • -daystart positional semantics (GNU find applies it only to predicates that follow it in the expression)

🤖 Generated with Claude Code

@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Mar 16, 2026

@codex conduct a comprehensive security and code review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fe7df3ff90

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread builtins/find/find.go Outdated
Comment thread builtins/find/find.go Outdated
Comment thread builtins/find/eval_predicates.go Outdated
Comment thread builtins/find/expr.go Outdated
@matt-dz matt-dz changed the title feat(find): add --help, -type b/c, and 21 GNU find predicates feat(find): add --help, -type b/c, -readable, -perm, -quit Mar 16, 2026
@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Mar 16, 2026

@codex conduct a comprehensive security and code review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 87f4b726dc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread builtins/find/match.go Outdated
Comment thread builtins/find/expr.go Outdated
@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Mar 16, 2026

@codex conduct a comprehensive security and code review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 26c0bc85b8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/scenarios/cmd/find/predicates/perm_exact.yaml Outdated
Comment thread builtins/find/find.go Outdated
@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Mar 16, 2026

@codex conduct a comprehensive security and code review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2d84c9773d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread builtins/find/expr.go
@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Mar 16, 2026

@codex conduct a comprehensive security and code review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f6c223d8b9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread builtins/find/find.go
Comment thread builtins/find/expr.go Outdated
Comment thread tests/scenarios/cmd/find/predicates/quit_or_short_circuit.yaml Outdated
@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Mar 16, 2026

@codex conduct a comprehensive security and code review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 80e3e4b007

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread builtins/find/find.go Outdated
Comment thread builtins/find/expr.go Outdated
Comment thread tests/scenarios/cmd/find/predicates/quit_first_match.yaml Outdated
@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Mar 16, 2026

@codex conduct a comprehensive security and code review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e5ea737dd8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread builtins/find/eval.go Outdated
Comment thread builtins/find/find.go
matt-dz and others added 4 commits March 17, 2026 08:50
Add --help to the find builtin (required by RULES.md for every command)
and extend -type to support block (b) and character (c) device types
for GNU find parity.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cover fileTypeChar, matchType, and parseTypePredicate with unit tests,
plus a scenario test validating parser acceptance of -type b, c, and b,c.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add permission (-readable, -writable, -executable, -perm), time
(-atime, -amin, -ctime, -cmin), ownership (-user, -group, -uid, -gid,
-nouser, -nogroup), link (-links, -inum, -samefile), action (-ls,
-printf, -quit), and global option (-daystart, -depth, -mount/-xdev)
predicates. All are read-only and safe for the AI agent sandbox.

Includes platform-specific stat helpers (Linux/Darwin/Windows),
unit tests for parser and matchPerm, and 14 scenario tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add symbols required by the new find predicates to both the global
ceiling and find per-command allowlist: io/fs.FileMode, os/user
lookups, syscall.Stat_t, syscall.Win32FileAttributeData, time.Date,
time.Unix, strconv.FormatUint, and others.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
No YAML scenarios reference skip_if_root after removing the
root-sensitive readable and test_write_denied scenarios.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Mar 18, 2026

@codex conduct a comprehensive security and code review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bfbe097394

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/scenarios/cmd/test/files/test_exec_check.yaml Outdated
Comment thread allowedpaths/sandbox_windows_test.go Outdated
matt-dz and others added 3 commits March 18, 2026 11:10
Duplicate of test_x_executable (which also covers missing files).
Its stdout_windows expectation was stale after the Windows execute-deny
fix in 1ac97c4.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
TestAccessExecAlwaysSucceedsWindows asserted NoError but the
implementation (1ac97c4) returns ErrPermission for execute checks.
Rename to TestAccessExecAlwaysDeniedWindows and assert ErrorIs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Mar 18, 2026

@codex conduct a comprehensive security and code review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@matt-dz matt-dz changed the title feat(find): add --help, -type b/c, -readable, -perm, -quit feat(find): add --help, -type b/c, -perm, -quit; fix access TOCTOU Mar 18, 2026
Copy link
Copy Markdown
Collaborator Author

@matt-dz matt-dz left a comment

Choose a reason for hiding this comment

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

Effective Go Review — PR #104

[Claude Opus 4.6] Reviewed 13 changed Go files (1688 added lines) against Effective Go and 100 Go Mistakes.

Overall assessment: ✅ All clear — no P0/P1 findings.

Positive observations

  • Excellent TOCTOU prevention in accessCheck — open-first with O_NONBLOCK, fstat for metadata from the same inode
  • Proper errors.Is() usage throughout
  • Well-structured guard clauses (e.g., if !checkRead early return)
  • Comprehensive doc comments on complex functions
  • Clean separation of root/non-root paths in effectiveHasPerm
  • Correct quit-before-implicit-print evaluation order matching GNU find

Minor observations (P3, not blocking)

# Priority File Finding Rule
1 P3 Badge portable_unix.go:58 f.Close() discards error #54 Defer errors
2 P3 Badge portable_windows.go:76 f.Close() discards error #54 Defer errors

Both are on read-only file descriptors opened for permission probing — close errors are benign (no unflushed data). Acceptable trade-off for the access-check hot path.

🤖 Generated with Claude Code

Read-only fds rarely fail on close, but Effective Go (#54) requires
checking. Capture and return close errors instead of discarding them.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Mar 18, 2026

@codex conduct a comprehensive security and code review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0402635107

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread allowedpaths/portable_windows.go Outdated
matt-dz and others added 2 commits March 18, 2026 12:09
…ype-bc

# Conflicts:
#	LICENSE-3rdparty.csv
#	allowedsymbols/symbols_builtins.go
#	go.mod
accessCheck discarded checkWrite, so Access(..., 0x02) always
succeeded — even for read-only files. On Windows,
FILE_ATTRIBUTE_READONLY clears write bits in Mode().Perm(), making
mode-bit inspection reliable. Capture checkWrite and deny when the
owner write bit is clear.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Mar 18, 2026

@codex conduct a comprehensive security and code review

The merge from main replaced our symbols_builtins.go, dropping
find-specific symbols (io/fs.FileMode, ModeCharDevice, ModeDevice,
ModeSetuid, ModeSetgid, ModeSticky, strconv.ParseUint, strings.Split).
Re-add them to both per-command and global lists.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Mar 18, 2026

@codex conduct a comprehensive security and code review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@matt-dz matt-dz marked this pull request as ready for review March 18, 2026 16:38
@matt-dz matt-dz enabled auto-merge March 18, 2026 16:40
@matt-dz matt-dz added this pull request to the merge queue Mar 18, 2026
Merged via the queue into main with commit 28826a6 Mar 18, 2026
30 checks passed
@matt-dz matt-dz deleted the find-help-and-type-bc branch March 18, 2026 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants