Skip to content

Deferred minor findings from the #43/#47/#50/#51 review cycles #55

Description

@abienkowski

Problem

The review processes for #45 (PR #47), #24 (PR #43), #39 (PR #50) and #48 (PR #51) produced a set of deliberately deferred Minor findings — real but not merge-blocking. Recording them here so they stop living only in session logs.

Cross-language parity (smallest first)

  • HEAD on a named container: HEAD /containers/x — Go and TS allow via the GET/HEAD passthrough; Rust denies in its lifecycle branch (rs/src/proxy.rs catch-all). Related to Routing parity: TS path-wide exec deny; Go matchEndpoint accepts endpoint subpaths #49.
  • Numeric gid edge parity (--listen-socket-group): negative values — Go rejects with "negative gid", Rust/TS fail via name lookup; leading + — all three now reject (post-feat!: dockerd-parity listening socket, Unix path only #47 fix) but via different paths; oversized values fail differently per language. Behaviourally all deny; messages differ.
  • Name-lookup gid range: Go's pure-Go resolver and TS's /etc/group parser don't range-check a gid obtained by name lookup (the digits-only path does). Exploiting it requires control of /etc/group.
  • Probe "other connect error" messages differ by OS error wording (Go connect: permission denied vs Rust Permission denied (os error 13) vs Node connect EACCES); tests assert the refusing to remove prefix only.
  • Linux full-backlog probe: a live listener with a full backlog → Rust times out → "in use by another process"; Go gets EAGAIN → "refusing to remove … resource temporarily unavailable". Both safe (nothing unlinked); message diverges.

Listener (from #45's reviews)

  • macOS full-backlog live listener can return ECONNREFUSED → probe treats it as stale (only lockless peers exposed; Go/Rust hold the flock).
  • Lstat→Remove window: a lockless process's swapped-in file could be removed (tiny race, design accepts it).
  • Rust leaves the 0600 socket file on disk when chown/chmod fails (Go's Close unlinks); pre-existing parity gap.
  • SIGKILL test child can leak on t.Fatal in Go (add t.Cleanup); GC test passes partly by construction.
  • Concurrency-test losers in Go assert a substring ("is in use by another"), Rust asserts the exact message.
  • EPERM tests could also skip when getegid()==0.

Tests & tooling

  • Integration checks assert HTTP status only; asserting the deny body ("not allowed") would stop a daemon-side 403 masking a proxy regression (no authz plugin in the test stack today, so theoretical).
  • Rust/TS route-table tests stop at the first failing row; Go uses t.Run per row.
  • Go's extractContainerName empty-string test documents the contract but can't fail for the Rust extract_container_name treats empty segment as a container name (DELETE /containers/ is forwarded) #48 cause ("" is both "no name" and the raw value).
  • Go flag-removal test builds the binary in-test; TS VALUE_FLAGS/BOOL_FLAGS exported mutable.
  • ROUTER_SPEC := vs ?= used by the other Makefile spec vars.
  • test-sock.sh has a duplicate "GET /_ping -> 200" label (granted vs default-group).

Docs

Proposed solution

Work through these in one or two chore:/docs:/test: PRs, or pick items off when touching the files anyway. None changes behaviour except the parity items, which should each get the #24/#48 treatment (decide canonical row, converge, pin with same-named tests).

Which implementation(s) would this affect?

  • Go
  • Rust
  • TypeScript
  • Quint specification
  • CI / infrastructure

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type: MaintenanceAdded to issues and PRs when a change is for repository maintenance , such as CI or linter changes.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions