Skip to content

fix: answer a request only with a Response or a Report - #49

Merged
ilyam8 merged 3 commits into
masterfrom
engine-reply-pdu-type
Oct 12, 2026
Merged

ilyam8 merged 3 commits into
masterfrom
engine-reply-pdu-type

Conversation

@ilyam8

@ilyam8 ilyam8 commented Oct 11, 2026 •

Copy link
Copy Markdown
Member

Summary

The client accepted a packet that is not a response as the answer to its request. A request sent back unchanged (by a
loop, a misconfigured proxy, a NAT hairpin, or any on-path sender, with no key needed) carries the client's own msgID,
request ID and, when authenticated, its own digest and ciphertext, so it passed every check and was returned as a
successful reply at every security level: a Get returned its own Null varbinds, and a Set reported success although
no agent received it.

answers now takes a reply only as a Report or a Response, as net-snmp does (it matches only Response and Report PDUs
to outstanding requests).

Behavior

  • A reply that is not a Report the client maps answers a request only as a Response (GetResponse); a request PDU, a
    trap or any other PDU type is read past, in every SNMP version, as are Reports from SNMPv1 or SNMPv2c messages.
  • The empty-reply rule now applies to Responses only. Before, a reflected discovery request (it carries no varbinds)
    was taken as the discovery answer, and an authenticated request then failed for want of a key; now it is read past
    and the retry discovers the engine.
  • A Report with more than one varbind is read past (RFC 3412 section 7.1 step 3 d builds Reports with one varbind; it
    was returned as a successful reply). net-snmp maps such a Report by its first varbind instead.
  • Unchanged and still pinned as known bugs: a Response with request ID 0 answers any request; an empty Response without
    an error status answers before its request ID is checked; the security model, level and context of a reply are not
    compared with the request's.

Commits

  • test: reflected requests (Get at noAuthNoPriv and authNoPriv, Set at authNoPriv and authPriv, an SNMPv2c Get),
    pinned on the code before the fix with the fake agent's new reflect answer.
  • fix: the PDU-type check in answers; five pinned known bugs flip (requests/answer/{not-a-response,report,v1-trap},
    v3/answer/report-two-varbinds{,-error-oid}).
  • test: a reflected discovery request.

Validation

  • Engine goldens: only the reflection pins and the five known bugs change; walk and v3-fips unchanged.
  • Six mutation probes of the change, including the order of the empty-reply rule: all killed.
  • go test -race, FIPS 140-only, GOARCH=386, the end-to-end suite against snmpd 5.9.3, golangci-lint, cross-builds,
    govulncheck: pass locally.
  • The correction was proposed and validated by an external final review of the previous PR, which found the bug.

The fake agent can reflect a request. A reflected request carries the
client's own msgID, request ID and, when authenticated, its own digest
and ciphertext, and the client returns it as a successful reply: a Get
at noAuthNoPriv and authNoPriv, a Set at authNoPriv and authPriv, and an
SNMPv2c Get.
answers never checked the reply's PDU type, so a request sent back
unchanged, which carries the client's own msgID, request ID and digest,
was returned as a successful reply at every security level, a Set
included. A reply that is not a Report reportKindOf maps now answers
only as a Response (GetResponse), as in net-snmp; other PDU types, and a
Report with more than one varbind, are read past.
The discovery request carries no varbinds, so before the PDU-type check
the empty-reply rule took it, reflected, as the discovery answer, and an
authenticated request then failed for want of a key. It is read past now
and the retry discovers the engine.
@ilyam8 ilyam8 changed the title engine reply pdu type fix: answer a request only with a Response or a Report Oct 11, 2026
@ilyam8
ilyam8 marked this pull request as ready for review October 11, 2026 16:31
@ilyam8
ilyam8 merged commit 6c4c998 into master Oct 12, 2026
21 checks passed
@ilyam8
ilyam8 deleted the engine-reply-pdu-type branch October 12, 2026 06:59
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