carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

| Finding | Disposition | Reason | |---|---|---| | 10 | Closed for the original bypass | The listener now requires a successful self-test, and both listener and proxy are bound to that test’s lifetime. §6.2 also requires scanner-side readiness before wiring. A separate boot-ordering defect remains below. | | 11 | Closed | Both scan limits are fixed at 100 MiB; §3.5 bounds the configurable stream limit so the specified fixtures fit. |

Reviewed draft 5 at edee53d4. No files changed or live-box tests performed.

  1. P2 — §§3.2–3.3: The gated socket creates a boot-ordering cycle with systemd’s default dependencies.

The specified socket dependency orders scanner-tcp.socket after scanner-selftest.service, but neither unit disables default dependencies. On reboot, this produces the following cycle, where each arrow means “must start before”:

``text scanner-tcp.socket → sockets.target → basic.target → scanner-selftest.service → scanner-tcp.socket ``

Code evidence: systemd adds Before=sockets.target to sockets in src/core/socket.c:262, adds After=basic.target to services in src/core/service.c:712, and orders basic.target after sockets.target in units/basic.target:13.

Systemd resolves an ordering cycle by deleting a dispensable job or rejecting the transaction; it cannot execute the specified startup sequence intact. See src/core/transaction.c:351–395. Consequently, the scanner can remain unavailable after reboot. Initial cloud-init startup and §3.3’s kill/restart checks can miss this because basic.target and sockets.target have already completed.

Fix: Specify DefaultDependencies=no for scanner-tcp.socket, restore its initialization and shutdown dependencies explicitly, and arrange activation through clamd or multi-user.target without ordering it before sockets.target. Retain the self-test dependencies. Add a reboot acceptance check and verify the complete boot transaction for ordering cycles.

The other requested mechanisms do not produce additional findings:

  • Self-test state: Type=oneshot delays ordered dependents until successful completion. RemainAfterExit=yes retains that success as active (exited); it neither overrides BindsTo= nor preserves success across reboot. A failed test cannot authorize the listener. Service semantics.
  • Clamd restart and package restart: BindsTo= plus After= stops dependents when clamd becomes inactive or fails; explicit restarts also propagate. Applying this to both TCP units removes the listener and terminates the proxy holding established connections. Requires= alone does not cover unexpected deactivation. Dependency semantics.
  • Automatic recovery: With the default RestartMode=normal, automatic restart creates a new start transaction with dependency restart propagation. That transaction processes Wants=scanner-tcp.socket, which pulls in the self-test again. This is supported by service.c:2405–2418 and transaction.c:937–947.
  • INSTREAM: systemd-socket-proxyd forwards bidirectional stream bytes between TCP and Unix sockets. The client’s INSTREAM implementation uses byte framing, without descriptor passing, so the proxy supports its protocol. Proxy semantics.

After fixing the boot cycle, the gating design is sound at spec level. Actual restart timing, connection termination and EICAR transport belong to the real-box acceptance checks.

Verdict: accept with fixes.