Skip to content

Reject out-of-order pairing messages - #24

Merged
JaredP94 merged 3 commits into
mainfrom
fix/pairing-state-guards
Nov 2, 2026
Merged

JaredP94 merged 3 commits into
mainfrom
fix/pairing-state-guards

Conversation

@JaredP94

@JaredP94 JaredP94 commented Nov 2, 2026

Copy link
Copy Markdown
Owner

Description

Out-of-order pairing messages could crash either side or grant trust without the PIN:

  • The inviter checked a Completion MAC against a still-empty key when the message arrived before the PIN was applied. An empty-key MAC over the public transcript needs no PIN, so it could reach Registered.
  • A key-exchange message before negotiation dereferenced the unselected algorithm and panicked either role. On the joiner that panic held the session lock, so the slot was never reclaimed; repeating it could exhaust the 64 pending sessions.
  • The joiner accepted EAP-Success in any state, storing an association without verifying the server's Completion MAC.

Completion now requires derived keys (Waiting, or OOBReceived in the peer-to-server direction this fork still supports); key exchange requires negotiation; EAP-Success is accepted only right after a verified Completion. A terminal protocol error releases the joiner's session.

Ported from NVIDIA#184 (6c8fa90, 4f8b050, and the Success guard from 6a752f6). That PR's wider API cleanup is not included.

Scope

services/eap-noob, services/nvpair-cluster-manager/httpserver.go. No wire change.

Validation

  • go test ./... in eap-noob and nvpair-cluster-manager. The new inviter test reproduced the nil-pointer panic before the guard.
  • services/tests: all cluster_manager_test.go and tls_test.go cases (pairing, wrong PIN both sides, cancel/decline/expiry, fan-out, leave) — 23 passed.

Risk

Low. Valid pairings follow the same path; only messages that were never valid in that state are refused. nvpair-cluster-manager 2.1.0 → 2.1.1.

Checklist

  • I have read the Contributing Guidelines.
  • Every commit is signed off (git commit -s), certifying the Developer Certificate of Origin.
  • New or existing tests cover the change.
  • Relevant documentation is updated.
  • I checked the diff, changed filenames, and commit messages for credentials, private data, internal URLs, internal issue identifiers, and generated artifacts.
  • I recorded the validation commands and results above.
  • I bumped any affected component in services/versions.json, and described user-visible changes above so they reach the release notes.

Part of the upstream issue/PR review. Each branch is independent off main; they all bump services/versions.json, so the second one merged will need a trivial conflict resolution there.

JaredP94 and others added 3 commits November 2, 2026 15:18
A pairing message that arrives out of order could crash either side or
grant trust without the PIN:

- The inviter checked a Completion MAC against an empty key when the
  message arrived before the PIN was applied. An empty-key MAC over the
  public transcript is computable without the PIN, so it could reach
  Registered.
- A key-exchange message sent before negotiation dereferenced the
  algorithm negotiation selects, panicking either role.
- The joiner accepted EAP-Success in any state, storing an association
  without verifying the server's Completion MAC.

Completion now requires derived keys, in Waiting or (peer-to-server
direction) OOBReceived. Key exchange requires negotiation. EAP-Success is
accepted only directly after a verified Completion request.

Ported from NVIDIA#184 (6c8fa90, 4f8b050 and the
Success guard from 6a752f6), adapted to this fork's eap-noob, which still
supports the peer-to-server direction.

Co-authored-by: Kaylee Lubick <klubick@nvidia.com>
Signed-off-by: Jared Ping <13906915+JaredP94@users.noreply.github.com>
…l error

A pairing message that panicked inside the joiner left its session mutex
locked, so expiry could never reclaim it; repeating that could exhaust the
pending-session slots until restart. A terminal protocol error also left
its session behind.

Scope the joiner's message handling with a deferred unlock, delete the
session on terminal protocol errors as well as processing errors, and
notify after unlocking.

Ported from NVIDIA#184 (4f8b050).

Co-authored-by: Kaylee Lubick <klubick@nvidia.com>
Signed-off-by: Jared Ping <13906915+JaredP94@users.noreply.github.com>
Signed-off-by: Jared Ping <13906915+JaredP94@users.noreply.github.com>
@JaredP94
JaredP94 force-pushed the fix/pairing-state-guards branch from 8b07749 to f8d49a4 Compare November 2, 2026 18:22
@JaredP94
JaredP94 merged commit ba12848 into main Nov 2, 2026
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.

1 participant