Skip to content

ext/snmp: fix buffer overflow in suffix-as-keys OID construction#21341

Open
thomasvincent wants to merge 1 commit intophp:masterfrom
thomasvincent:fix/snmp-suffix-key-buffer-overflow
Open

ext/snmp: fix buffer overflow in suffix-as-keys OID construction#21341
thomasvincent wants to merge 1 commit intophp:masterfrom
thomasvincent:fix/snmp-suffix-key-buffer-overflow

Conversation

@thomasvincent
Copy link

The suffix-as-keys code path in php_snmp builds a dotted OID suffix
string by repeatedly calling snprintf into a temporary buffer and
appending with strcat into the fixed 2048-byte buf2 array. There is
no bounds check, so a deeply nested OID with many large numeric
components from a malicious SNMP agent could overflow the stack buffer.

Replace the strcat loop with direct snprintf into buf2 at a tracked
offset, breaking out of the loop if the buffer would be exhausted.

The MAX_OID_LEN (128) with maximum-length 32-bit components (10 digits
plus dot each) can produce up to 1408 bytes of suffix text, which fits
within the 2048-byte buffer under normal conditions. This patch adds the
safety net for the pathological case.

The suffix-as-keys code path in php_snmp builds a dotted OID suffix
string by repeatedly calling snprintf into a temporary buffer and
appending with strcat into the fixed 2048-byte buf2 array. There is
no bounds check, so a deeply nested OID with many large numeric
components from a malicious SNMP agent could overflow the stack
buffer.

Replace the strcat loop with direct snprintf into buf2 at a tracked
offset, breaking out of the loop if the buffer is exhausted.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
@thomasvincent
Copy link
Author

Closing to re-evaluate the appropriate disclosure channel.

@thomasvincent
Copy link
Author

Reopening as a defense-in-depth hardening fix.

After further analysis, the underlying condition (OID name_length > 128 subidentifiers) is prevented by net-snmp's BER decoder: asn_parse_objid() enforces MAX_OID_LEN and returns NULL if the wire-format OID exceeds the output buffer, causing snmp_pdu_parse() to abort the entire PDU. With MAX_OID_LEN=128 and max 10-digit subidentifiers, the worst-case suffix string is 128 * 11 = 1408 bytes, within the 2048-byte buffer.

However, net-snmp has had historical CVEs in its OID parser (e.g., CVE-2019-20892), so this bounds-checked approach provides a safety net against future parser regressions. The fix replaces the unbounded strcat loop with snprintf at a tracked offset, which is also cleaner code regardless of the overflow risk.

@thomasvincent thomasvincent reopened this Mar 4, 2026
@ndossche
Copy link
Member

ndossche commented Mar 4, 2026

FWIW, I agree this does not fix an actual issue but is a hardening patch.
I remember looking at this a while ago too and concluding the overflow is actually impossible.
I think the commit/PR title should be updated to reflect that.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants