Skip to content

M168: Fault injection and hostile-endpoint testing for the socket transport - #18

Merged
rickenator merged 1 commit into
masterfrom
copilot/continue-where-we-left-off
Jul 5, 2026
Merged

M168: Fault injection and hostile-endpoint testing for the socket transport#18
rickenator merged 1 commit into
masterfrom
copilot/continue-where-we-left-off

Conversation

Copilot AI commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Implements Milestone 168: extend Phase 1's hostile-input testing tradition to the M162 out-of-process transport boundary. Queue-full, out-of-order/duplicate KV appends, DMA descriptor rejection, endpoint crash mid-decode, and malformed completions must all map to att1_status_t cleanly, without UB.

New fault-injection test suite

  • tests/test_aimu_endpoint_fault_injection.c exercises five scenarios against a real att1-aimu-endpoint daemon process (plus one hostile mock daemon):
    • Queue-full over the socket transport
    • Out-of-order and duplicate KV appends
    • Malformed DMA descriptors (unaligned address, unsupported flags, zero length)
    • Daemon crash mid-decode (SIGKILL between submit and poll)
    • A minimal hostile mock daemon that speaks just enough of the wire protocol to send back deliberately malformed completions (oversized kv_key_bytes/kv_value_bytes/payload_bytes claims)
  • tools/att1-aimu-endpoint.c gains --cmd-ring-depth/--comp-ring-depth CLI overrides so queue-full doesn't require filling the 64-deep default ring.

Two real defects found and fixed

Writing the crash-mid-decode and malformed-completion cases surfaced actual bugs, not just missing coverage:

  • SIGPIPE kills the client on daemon crash. src/aimu_endpoint_protocol.c used a plain write(); once the peer had crashed, that raises SIGPIPE, whose default disposition terminates the client process instead of returning ATT1_ERR_IO. Fixed by switching to send(..., MSG_NOSIGNAL).
  • Out-of-bounds read from a hostile/buggy daemon response. client_kv_read(), client_kv_copy_range(), and client_fabric_receive() in src/aimu_endpoint_client.c clamped daemon-reported lengths only against the caller's own buffer capacity, not against the wire payload's actual capacity (ATT1_AIMU_ENDPOINT_MAX_PAYLOAD). A malformed response claiming an oversized length, combined with a sufficiently large caller buffer, could read past the local att1_aimu_endpoint_response struct. All three now clamp against both bounds before any memcpy, and client_fabric_receive()'s reported byte count now always matches what was actually copied.

Docs

  • docs/PHASE2_PLAN.md, docs/OPERATION_LOG.md, and compiler/check_docs.py updated to reflect M168 complete / M169 active.

@rickenator
rickenator marked this pull request as ready for review July 5, 2026 04:24
@rickenator
rickenator merged commit a1215c4 into master Jul 5, 2026
2 checks passed
@rickenator
rickenator deleted the copilot/continue-where-we-left-off branch July 5, 2026 04:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants