feat(ping): implement ping builtin#118
Conversation
Plan: Implement ping BuiltinContextThe rshell4 project implements a safe shell interpreter for AI agents. The user wants to add a ping builtin that uses the Approved DesignFlags to implement
Dangerous flags not implemented (rejected by pflag as unknown):
Privilege mode: auto-detect
Output format (matching real ping)
Safety constraints
Rounding of RTT outputMatch real ping: use Files to create/modify
Implementation outline for
|
Adds a ping builtin that sends ICMP echo requests using github.com/prometheus-community/pro-bing. Supports -c (count, max 20), -W (per-reply timeout), -i (interval, min 200ms), -q (quiet), -4/-6 (force address family). Dangerous flags (-f flood, -b broadcast, -s size, -I interface, -p pattern, -R record-route) are rejected. Auto-detects privilege: tries unprivileged UDP-based ICMP first, falls back to raw socket on EPERM/EACCES. Enforces a hard total deadline capped at 120s. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
AlexandreYang
left a comment
There was a problem hiding this comment.
Review Summary
Reviewed the ping builtin implementation. The overall design is solid: input clamping, context deadlines with a 120s hard cap, blocked dangerous flags, unprivileged-first with privilege fallback, comprehensive pentest and fuzz test coverage. Two blocking issues will cause CI to fail before this can merge.
Overall assessment: needs fixes
Positive observations
- Input clamping for
-c,-W, and-iwith hard upper caps prevents resource exhaustion. - Hard 120-second total deadline ensures the builtin cannot block indefinitely.
- Dangerous flags (
-f,-b,-s,-I,-p,-R) are correctly blocked via pflag's unknown-flag rejection — no explicit deny-list needed. isPermissionErruseserrors.Ischain traversal with a string-based fallback for Windows, which is the correct cross-platform approach.- Unprivileged-first strategy avoids requesting raw socket capabilities unnecessarily.
- Fuzz targets (
FuzzPingFlags,FuzzPingHostname) with seed corpus cover the main attack surfaces. - No filesystem access,
os/exec, orunsafein the implementation.
|
@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. |
|
Iteration 1 self-review result: REQUEST_CHANGES Findings: 4 total (2×P1, 1×P2, 1×P3) Summary:
|
… comment - Fix gofmt indentation for ping.Cmd in interp/register_builtins.go - Add pro-bing, google/uuid, golang.org/x/net, golang.org/x/sync to LICENSE-3rdparty.csv (TestComplianceLicense3rdPartyCompleteness) - Replace stderr_contains with expect.stderr in flood/broadcast/unknown flag rejection scenarios (AGENTS.md convention) - Add comment explaining the redundant DNS lookup in privilege fallback Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
[Claude Sonnet 4.6] Addressed review feedback from @AlexandreYang:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4a44531948
ℹ️ 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".
AlexandreYang
left a comment
There was a problem hiding this comment.
Review Summary
Reviewed the ping builtin implementation (PR #118). The core logic, security model, test coverage, and documentation are well-structured. However, the PR is blocked by 3 failing CI checks that must be fixed before merging.
Findings
Positive observations
- Excellent security posture: all DoS-capable flags (
-f,-b,-s,-I,-p,-R) are explicitly blocked and tested - Hard total timeout cap (120s) and per-field clamping prevent resource exhaustion
- Context cancellation properly propagated through
RunWithContext - Unprivileged → privileged fallback is sound and handles error chain correctly
- Comprehensive pentest and fuzz test suites
- Scenario tests all have
skip_assert_against_bash: true(correct — bash ping output varies by system)
Overall: needs fixes (3 items, 2×P1 blocking CI)
|
@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. |
|
Iteration 1 self-review result: COMMENT 2×P1, 1×P2 findings:
Proceeding to fix these. |
- Add ping entry to builtinPerCommandSymbols with all required symbols - Add missing stdlib symbols (context.WithTimeout, strings.Contains, syscall.EACCES/EPERM, time.Millisecond) to builtinAllowedSymbols - Add pro-bing package symbols to builtinAllowedSymbols - Fix gofmt misalignment in TestDurToMS comment (ping_internal_test.go) - Add '"' to FuzzPingFlags metacharacter filter to prevent fuzz corpus entries with unescaped double-quotes from causing shell parse errors Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e90fff23ba
ℹ️ 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".
…pace The fuzz engine found a '\''\'' (single quote) in the generated flag+value string that caused a shell parse error. Also exclude backslash and space since they can similarly break the shell script template. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ll-safe chars Replace the character denylist with an allowlist: only letters, digits, hyphens, and dots are permitted in flag+value. This prevents the fuzzer from generating inputs with shell metacharacters (parens, brackets, etc.) that cause spurious parse errors unrelated to ping flag handling. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ters
Apply the same allowlist approach as FuzzPingFlags: only allow letters,
digits, hyphens, dots, and colons (for IPv6) in the hostname argument.
This prevents shell parse errors from characters like '(' that the
previous denylist did not cover.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@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. |
AlexandreYang
left a comment
There was a problem hiding this comment.
Iteration 2 self-review — COMMENT (REQUEST_CHANGES intent)
2 P2 findings remain. Both are in buildPinger in builtins/ping/ping.go.
| # | Priority | File | Finding |
|---|---|---|---|
| 1 | P2 | builtins/ping/ping.go:191 |
DNS resolution not bounded by runCtx context deadline |
| 2 | P2 | builtins/ping/ping.go:199-202 |
Conflicting -4/-6 flags silently prefer IPv4 instead of rejecting |
|
Iteration 2 self-review result: COMMENT (2 findings). Summary: 2 P2 findings remain — both in
Fixing both now. |
- buildPinger now accepts a ctx parameter and calls probing.NewPinger in a goroutine, selecting on ctx.Done() so that DNS resolution is bounded by the runCtx deadline (fixes P2: DNS not bounded by context) - Add explicit mutual-exclusion check: -4 and -6 together now return an error instead of silently preferring IPv4 (fixes P2: conflicting flags) - Add fmt.Errorf to ping per-command allowlist in symbols_builtins.go - Add scenario test for -4/-6 conflict Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0d5ea98ecd
ℹ️ 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".
|
@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. |
AlexandreYang
left a comment
There was a problem hiding this comment.
Iteration 3 self-review — APPROVE (no new findings)
Reviewed commit 12e94b5 which adds:
- Context-aware DNS resolution in
buildPinger(goroutine +select ctx.Done()) - Mutual-exclusion check for
-4/-6flags fmt.Errorfadded to ping per-command allowlist- Scenario test for
-4 -6conflict
Security
- DNS resolution now bounded by
runCtxdeadline ✓ - Conflicting flags rejected with clear error message ✓
- No new imports; no banned symbols ✓
- No filesystem access outside sandbox ✓
Correctness
buildPingeracceptsctxas first parameter; both callers passctx✓- Retry path (privileged fallback) passes already-resolved IP string to avoid redundant DNS ✓
- Mutual exclusion check before DNS resolution ✓
allowedsymbolstests pass ✓
Test coverage
- New scenario
ipv4_ipv6_conflict.yamlcovers the mutual-exclusion error path ✓ - All ping tests pass ✓
CI
- All checks passing except
Allowed Symbols Label Check(human-gated per AGENTS.md) ✓
Overall: no findings. PR is clean pending human review of allowed symbols.
|
Iteration 3 self-review result: APPROVE (no findings on commit 12e94b5). All P2 findings from iterations 1-2 are resolved. CI is clean except the human-gated Allowed Symbols Label Check. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 12e94b5712
ℹ️ 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".
buildPinger now calls net.ResolveIPAddr(resolveNet, host) in the goroutine where resolveNet is "ip4", "ip6", or "ip" depending on flags. This ensures dual-stack hosts resolve to the correct address family when -4 or -6 is specified, fixing the P1 finding. The resolved IP string is passed to probing.NewPinger which returns immediately (no second DNS round-trip). The original host argument is preserved in execPing for display in the PING header and statistics footer so output still shows the hostname, not the raw IP. Also adds net.IPAddr and net.ResolveIPAddr to the allowlist. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@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. |
AlexandreYang
left a comment
There was a problem hiding this comment.
Iteration 4 self-review — APPROVE (no new findings)
Reviewed commit 7242f5e which fixes the DNS family selection P1:
buildPingernow callsnet.ResolveIPAddr(resolveNet, host)in the goroutine with correct family (ip4/ip6/ip)execPinguses originalhostfor PING header and statistics footer displayprintStatstakeshost stringparameter;stats.Addr(which would show the IP) is no longer used in displaynet.IPAddrandnet.ResolveIPAddradded to ping per-command allowlist andbuiltinAllowedSymbols
Security: No new imports beyond net (base package, not banned). DNS is still context-bounded via goroutine + select.
Correctness: Retry path passes pinger.IPAddr().String() (already an IP) → net.ResolveIPAddr returns immediately without DNS. No goroutine leak: buffered channel (capacity 1) ensures the goroutine always drains.
Overall: no findings.
|
Iteration 50 self-review result: APPROVE — 0 findings. Code is ready to merge. All previously identified issues have been fixed; the two documented intentional limitations (isScopedIPLiteral naming, directed-broadcast spin-loop) have been accepted. gofmt clean, all tests pass. |
|
Codex Review: Didn't find any major issues. Can't wait for the next one! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
AlexandreYang
left a comment
There was a problem hiding this comment.
Review Summary (iteration 51 — confirming APPROVE)
Reviewed the ping builtin implementation at commit 70963f3e. This is a fresh re-review confirming the prior APPROVE from iteration 50.
Overall assessment: safe to merge. No new issues found.
What was reviewed
builtins/ping/ping.go— full implementation (593 lines)builtins/ping/ping_internal_test.go— white-box tests for helpersbuiltins/ping/ping_test.go— integration/functional testsbuiltins/ping/builtin_ping_pentest_test.go— security/DoS test vectorsbuiltins/ping/ping_fuzz_test.go— fuzz harnessestests/scenarios/cmd/ping/— 25 scenario YAML filesallowedsymbols/symbols_builtins.go— allowed-import list updatesSHELL_FEATURES.md,LICENSE-3rdparty.csv,go.mod/go.sum
No findings
| # | Priority | File | Finding |
|---|---|---|---|
| — | — | — | No issues found |
Positive observations
- Sandbox integrity preserved: no
os.Open,os.Stat, or filesystem access; network I/O goes throughnet.DefaultResolverandpro-bing, both of which are explicitly whitelisted. - Dangerous flags blocked at parse time:
-f,-b,-s,-I,-p,-Rare unregistered and rejected by pflag before any code runs. - Broadcast/multicast/unspecified blocked post-resolution:
ip.IsUnspecified(),ip.IsMulticast(), and theip4[3] == 255check catch dangerous destinations regardless of how they were resolved (DNS or literal). The known limitation for non-standard subnet directed-broadcasts is documented in code andSHELL_FEATURES.md. - Hard 120 s ceiling:
maxTotalTimeoutcaps total run time; context cancellation is propagated through DNS andRunWithContext; all duration/count inputs are clamped with warnings. - Integer/float overflow safety:
parsePingDurationguards against NaN, Inf, andfloat64 → int64overflow; negative values are explicitly rejected. - Privileged fallback is clean:
buildPingeris called with the already-resolved numeric IP on retry, so no second DNS query and no zone-identifier loss for scoped IPv6 addresses. - Test coverage is thorough: white-box unit tests for every helper, pentest vectors for all dangerous flag classes, fuzz harnesses for both flags and hostnames, and 25 scenario YAML files covering flag validation, address rejection, and clamping warnings.
- Documentation up to date:
SHELL_FEATURES.mdentry and package godoc accurately describe behavior, limitations, and platform requirements.
|
@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. |
|
Iteration 51 self-review result: APPROVE — 0 findings. Code is clean and ready to merge. |
|
Codex Review: Didn't find any major issues. Nice work! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
AlexandreYang
left a comment
There was a problem hiding this comment.
Review Summary (iteration 52)
This is a fresh review of the ping builtin at HEAD 70963f3e. The implementation, tests, and documentation were re-examined end-to-end against all review dimensions.
Overall assessment: safe to merge. APPROVE (submitted as COMMENT because self-review is not permitted on GitHub).
What was reviewed
builtins/ping/ping.go— full implementationbuiltins/ping/ping_internal_test.go,ping_test.go,builtin_ping_pentest_test.go,ping_fuzz_test.go- All scenario YAML files under
tests/scenarios/cmd/ping/ allowedsymbols/symbols_builtins.goping entrySHELL_FEATURES.md,go.mod/go.sum,LICENSE-3rdparty.csv
Security (A)
- No direct filesystem access (
os.Open,os.Stat, etc.) — ping only performs DNS and ICMP network I/O. - No
os/exec,net/http, orunsafeimports. - Dangerous flags (
-f,-b,-s,-I,-p,-R) are rejected by pflag at parse time (exit 1) before any network I/O. - Broadcast, multicast, and unspecified destinations are rejected in
buildPingerbefore the pinger is created. The.255heuristic for directed-broadcast and its known false-positive are both documented and intentional (do not re-flag). - Context propagation is correct:
context.WithTimeoutwraps the outer shell context; DNS resolution, socket creation, and ICMP sends all respect the deadline. pro-bing.NewPingeris always called with a pre-resolved numeric IP, so the context-unaware internalnet.ResolveIPAddris a no-op (instant lookup, no goroutine leak).- The privileged socket retry path re-uses the already-resolved IP, so no second DNS round-trip can return a different address after the broadcast/multicast check.
isPermissionErrcannot be tricked by DNS errors because DNS errors are caught and returned bybuildPingerbeforeRunWithContextis ever called.maxTotalTimeout(120 s) provides a hard cap bounding any spin-loop risk from the pro-bing directed-broadcast retry bug on non-standard subnets (documented and intentional — do not re-flag).gofmt -lreports no violations.go vet ./builtins/ping/...is clean.- Allowed-symbols list accurately describes all imports.
Bash Compatibility / Correctness (B, C)
- All ping scenarios are correctly marked
skip_assert_against_bash: true. - Duration parsing: Go literals and plain integer/float seconds both accepted; negative, NaN, Inf, and overflow values are all rejected.
- Clamp warnings are emitted to stderr before DNS/ICMP. Exit codes are correct. Statistics are printed unconditionally.
icmp_seqis offset by +1 (POSIX convention).
Test Coverage (D)
- Scenario tests cover all flag rejection, address rejection, clamp-warning, and format/help cases.
- Go unit tests cover all unexported helpers.
- Pentest tests cover all attack vectors from the checklist.
- Fuzz tests cover flag parsing and hostname inputs.
- Network-dependent tests are gated behind
RSHELL_NET_TEST=1.
Documentation (E)
SHELL_FEATURES.mdentry is accurate and complete. Package-level doc comment documents all flags, exit codes, and output format.LICENSE-3rdparty.csvupdated.
No findings.
| # | Priority | File | Finding |
|---|---|---|---|
| — | — | — | No findings |
|
@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. |
|
Iteration 52 self-review result: APPROVE — 0 findings. Code confirmed clean (3rd consecutive APPROVE). |
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
AlexandreYang
left a comment
There was a problem hiding this comment.
Code Review — feat(ping): implement ping builtin (iteration 53)
Overview
This PR implements a ping builtin using github.com/prometheus-community/pro-bing v0.8.0. Reviewed the full diff including builtins/ping/ping.go, all test files, scenario YAMLs, allowedsymbols/symbols_builtins.go, SHELL_FEATURES.md, LICENSE-3rdparty.csv, and CI workflow changes.
The three commits since the last APPROVE (iterations 50–52) are minor cleanups:
isScopedIPLiteralsymbols (net.ParseIP,strings.IndexByte) added to both the per-command"ping"entry and the globalbuiltinAllowedSymbolslist.maxTotalTimeout = 120 * time.Secondnamed constant extracted (eliminates magic number).- Warning message derives the cap value from
maxTotalTimeout.Seconds()instead of a hardcoded"120s"string literal.
No new code logic was introduced. All changes are formatting/style/correctness improvements.
Assessment: safe to merge
Findings
None. No P0–P3 findings.
Security
- No filesystem access (
os.Open,os.Stat, etc.) — all I/O is ICMP/DNS, which is the explicit purpose of this builtin. - Dangerous flags (
-f,-b,-s,-I,-p,-R) rejected at flag-parse time before any network I/O. - Broadcast (last-octet
.255), multicast, and unspecified destinations rejected inbuildPingerbefore passing to pro-bing. - Context cancellation propagates into both DNS resolution (
LookupIPAddr/LookupIP) andpinger.RunWithContext. - Hard 120 s cap (
maxTotalTimeout) bounds worst-case wall-clock time even if all per-flag values are maxed. - No
os/exec,unsafe, ornet/httpimports. All new symbols are on the allowlist. isScopedIPLiteralcorrectly strips the%zonesuffix before callingnet.ParseIP— no injection surface.
Test Coverage
All code paths covered:
- 33 scenario YAML files covering blocked flags, address rejection, flag validation, clamping warnings, and help output — all marked
skip_assert_against_bash: true(intentional divergence). - Go unit tests (
ping_test.go,ping_internal_test.go) cover internal helpers, flag acceptance, context cancellation, and network tests (gated onRSHELL_NET_TEST=1). - Pentest tests (
builtin_ping_pentest_test.go) exercise integer overflow, long hostnames, injection attempts, and context deadline safety. - Two fuzz targets (
FuzzPingFlags,FuzzPingHostname) with boundary-value seed corpora; CI fuzz job passes.
Known Intentional Limitations (previously accepted)
isScopedIPLiteralhandles IPv4+zone and IPv6+zone (documented in code comments).- Directed-broadcast spin-loop for non-standard subnets (e.g.
/25) is bounded bymaxTotalTimeout; documented inbuildPingercomment andSHELL_FEATURES.md.
CI
All 30 CI checks pass on the current HEAD (70963f3e).
|
@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. |
|
dummy |
|
Codex Review: Didn't find any major issues. Nice work! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
AlexandreYang
left a comment
There was a problem hiding this comment.
Review Summary
Reviewed the ping builtin implementation (PR #118, commit 70963f3).
Overall assessment: safe to merge.
No findings. This is a thorough, well-structured implementation.
Security
- No filesystem access bypasses — all output uses
callCtx.Outf/Errf; noos.Open,os.Stat, or raw file access added. - All six dangerous flags (
-f,-b,-s,-I,-p,-R) are rejected at flag-parse time by pflag; there is no code path that could accidentally enable them. - Broadcast (
.255heuristic), multicast (ip.IsMulticast()), and unspecified (ip.IsUnspecified()) destinations are all rejected beforeprobing.NewPingeris called, preventing the pro-bing v0.8.0 auto-SO_BROADCAST retry from sending broadcast traffic. - DNS resolution is context-aware (
net.DefaultResolver.LookupIPAddr/LookupIPwith the caller's context), avoiding goroutine leaks on cancellation. - On the privileged retry path, the already-resolved numeric IP is passed to
buildPinger, soprobing.NewPingercallsnet.ResolveIPAddrsynchronously with no network round-trip and no context-cancellation gap. - Import allowlist additions are all appropriate:
net.DefaultResolverand the fivepro-bingsymbols serve the explicit purpose of the builtin. Noos/exec,unsafe, ornet/http. - The two known intentional limitations (directed-broadcast spin-loop on non-standard subnets bounded by
maxTotalTimeout;isScopedIPLiteralhandling IPv4+zone and IPv6+zone) are both correctly documented and were pre-flagged in the review spec.
Correctness
- Duration parsing: overflow guard (
maxDurationSec), NaN/Inf rejection, and negative-value rejection are all present and tested. clampInt/clampDurationare correct and fully unit-tested.- Context cancellation propagates from the outer shell context into both the DNS lookup and
pinger.RunWithContext. - The
pinger = p2reassignment on privileged retry ensurespinger.Statistics()reflects packets sent by the second pinger, not the first (which sent zero). - Statistics are printed unconditionally — including on error and context-cancellation — matching POSIX
pingbehavior. - Exit code semantics: 0 iff at least one reply received, 1 otherwise; matches POSIX.
Test Coverage
Adequate. Every code path is covered:
| Code path | Coverage |
|---|---|
| All dangerous flags rejected | Scenario YAML + pentest Go tests |
| Broadcast / multicast / unspecified rejection | Scenario YAML |
| Duration parsing (Go literal, integer, float, overflow, NaN, Inf, negative) | ping_internal_test.go |
| clamp warnings (-c, -W, -i) | Scenario YAML |
| Total-time cap warning | Scenario YAML |
| Help flag | Scenario YAML + Go test |
| Missing / extra host args | Scenario YAML + Go test |
| Context cancellation | Go test (pentest + functional) |
| Fuzz: flags + hostnames | ping_fuzz_test.go |
| isPermissionErr (EPERM/EACCES/EPROTONOSUPPORT/string fallback) | ping_internal_test.go |
All scenario tests correctly carry skip_assert_against_bash: true.
Positive Observations
- The two-attempt (unprivileged → privileged) fallback is clean and well-commented.
- The
isScopedIPLiteralhelper correctly handles the zone-separator case thatnet.ParseIPrejects. - The broadcast heuristic false-positive is explicitly documented in code, a test scenario, and
SHELL_FEATURES.md. - Fuzz targets cover both the flag-parsing and hostname-resolution surfaces with carefully chosen seed corpora.
SHELL_FEATURES.mdand theDescriptionfield are both updated.
|
@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. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 70963f3ef0
ℹ️ 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".
| if ip4 := ip.To4(); ip4 != nil && ip4[3] == 255 { | ||
| return nil, fmt.Errorf("broadcast destination not allowed: %s", ip) |
There was a problem hiding this comment.
Block non-.255 directed broadcast addresses
The broadcast guard only rejects IPv4 destinations whose last octet is 255, so directed broadcasts on non-/24-style masks (for example a /25 broadcast like 192.168.1.127) are still treated as valid and can be sent. In those environments this defeats the stated safety guarantee that broadcast destinations are rejected before transmission, and with pro-bing’s Linux EACCES retry path it can still generate broadcast ICMP traffic instead of failing fast.
Useful? React with 👍 / 👎.
|
/merge |
|
View all feedbacks in Devflow UI.
The expected merge time in
DDCI response: DDCI is currently blocked for this repository. Please reach out in #ci-infra-support for additional information. |
AlexandreYang
left a comment
There was a problem hiding this comment.
Review Summary
Scope: PR #118 — ping builtin implementation (builtins/ping/ping.go, tests, scenarios, allowedsymbols, SHELL_FEATURES.md, go.mod/go.sum, LICENSE-3rdparty.csv, CI fuzz config).
Overall assessment: safe to merge. No findings (APPROVE intent — blocked from self-approving).
This is iteration 55; the two previously documented limitations are intentional and correctly excluded per the review brief:
isScopedIPLiteralhandling IPv4+zone and IPv6+zone — documented in function comment.- Directed-broadcast spin-loop for non-standard subnets — bounded by
maxTotalTimeout, documented inbuildPinger.
Security
- No direct filesystem access (
os.Open/os.Stat/etc.) — sandbox invariant maintained. - The one context-free
probing.NewPingercall receives only a pre-resolved numeric IP, making the synchronousnet.ResolveIPAddrinside it instantaneous with no goroutine leak. - Destination filtering (unspecified, multicast, last-octet-255) is applied before any ICMP socket is opened.
isPermissionErrstring matching is case-insensitive and covers known Unix and Windows variants.- Hard 120 s wall-clock cap via
context.WithTimeoutenforced beforeRunWithContext. - No
unsafe,os/exec, ornet/httpimports; import allowlist insymbols_builtins.gois correct and complete.
Correctness
parsePingDurationoverflow guard is correct:maxDurationSecis computed as integer division before float64 conversion, avoiding off-by-one in the overflow boundary.p.Timeout(pro-bing internal) andtotal(context deadline) are consistent:totaladdspingGracePeriodon top of the pro-bing timeout, giving the last packet's reply a window to arrive.- Statistics are printed unconditionally, mirroring POSIX behaviour on SIGINT/timeout.
err != nil && ctx.Err() == nilcorrectly suppresses the redundant error log on context cancellation.
Test Coverage
- Comprehensive: unit tests for all helpers (
clampInt,clampDuration,parsePingDuration,durToMS,isPermissionErr,isScopedIPLiteral), pentest tests for all blocked flags and boundary inputs, fuzz tests for flags and hostnames, scenario tests for all error paths and flag clamping. Network-dependent tests are gated behindRSHELL_NET_TEST=1.
Positive Observations
- Context-aware DNS resolution avoids goroutine leaks on cancellation.
- Pro-bing
NoopLoggerprevents internal library noise from leaking to the user. - All scenario tests correctly carry
skip_assert_against_bash: true. SHELL_FEATURES.md,allowedsymbols,LICENSE-3rdparty.csv, andgo.mod/go.sumare all consistently updated.
| # | Priority | File | Finding |
|---|---|---|---|
| — | — | — | No findings |
Summary
pingbuiltin usinggithub.com/prometheus-community/pro-bing-c,-W,-i,-q,-4,-6,-hflags with safety caps-f,-b,-s,-I,-p,-R) are rejected at flag parse time-Wand-i(iputils ping compatibility)