Skip to content

ext/snmp: hardening: replace unbounded strcat with offset-tracked snprintf - #21341

Open
somethingwithproof wants to merge 4 commits into
php:masterfrom
somethingwithproof:fix/snmp-suffix-key-buffer-overflow
Open

somethingwithproof wants to merge 4 commits into
php:masterfrom
somethingwithproof:fix/snmp-suffix-key-buffer-overflow

Conversation

@somethingwithproof

@somethingwithproof somethingwithproof commented Mar 4, 2026 •

Copy link
Copy Markdown

The suffix-as-keys code path in php_snmp builds a dotted OID suffix
string by appending with strcat into a fixed 2048-byte buf2 array.
The overflow is not reachable in practice: net-snmp's BER decoder
enforces MAX_OID_LEN=128, and the worst-case suffix (128 subidentifiers
at 11 bytes each) produces 1408 bytes, within the 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.
Defense-in-depth against future net-snmp parser regressions.

@somethingwithproof

Copy link
Copy Markdown
Author

Closing to re-evaluate the appropriate disclosure channel.

@somethingwithproof

Copy link
Copy Markdown
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.

@ndossche

ndossche commented Mar 4, 2026

Copy link
Copy Markdown
Member

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.

@somethingwithproof
somethingwithproof force-pushed the fix/snmp-suffix-key-buffer-overflow branch from a830ab1 to 6932afe Compare March 6, 2026 20:10
@somethingwithproof somethingwithproof changed the title ext/snmp: fix buffer overflow in suffix-as-keys OID construction ext/snmp: hardening: replace unbounded strcat with offset-tracked snprintf Mar 6, 2026
@somethingwithproof

Copy link
Copy Markdown
Author

Updated commit subject and PR title to reflect hardening.

Comment thread ext/snmp/snmp.c Outdated
@somethingwithproof
somethingwithproof force-pushed the fix/snmp-suffix-key-buffer-overflow branch from 6932afe to 9b32d54 Compare March 6, 2026 20:21
@somethingwithproof

Copy link
Copy Markdown
Author

Fixed, squashed into the single commit.

somethingwithproof added a commit to somethingwithproof/php-src that referenced this pull request Mar 6, 2026
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
somethingwithproof added a commit to somethingwithproof/php-src that referenced this pull request Mar 6, 2026
…check

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
@devnexen

devnexen commented Mar 7, 2026

Copy link
Copy Markdown
Member

This defensive programming change looks good to me.

…rintf

The suffix-as-keys code path in php_snmp builds a dotted OID suffix
string by appending with strcat into a fixed 2048-byte buf2 array.
The overflow is not reachable in practice: net-snmp's BER decoder
enforces MAX_OID_LEN=128, and the worst-case suffix (128 subidentifiers
at 11 bytes each) is 1408 bytes, within the buffer.

Replace the strcat loop with direct snprintf into buf2 at a tracked
size_t offset, breaking out of the loop if the buffer would be exhausted.
Defense-in-depth against future net-snmp parser regressions.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
…check

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
@somethingwithproof
somethingwithproof force-pushed the fix/snmp-suffix-key-buffer-overflow branch from f502e94 to 24e167a Compare October 20, 2026 10:35
@somethingwithproof

Copy link
Copy Markdown
Author

Rebased onto current master (4526719). The previously failing LINUX_X64_RELEASE_NTS job now passes at 24e167a, including the normal and function-JIT test phases: https://github.com/php/php-src/actions/runs/39409074447/job/118582150470

A fresh local Ubuntu 24.04 arm64 build also passed the SNMP suite: 42 tests passed, one skipped because its MIB file was not at the expected path. The new gh21341 test passed. The original failed job's log has expired, so I cannot attribute that historical failure.

The suffix-building loop remains unchanged in upstream; this is still defensive hardening under Net-SNMP's existing OID limits.

@ndossche
ndossche requested a review from devnexen October 25, 2026 22:02
Comment thread ext/snmp/tests/gh21341.phpt Outdated
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
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.

3 participants