Commit c0e07742e00 for php
commit c0e07742e005d49972d52ac1d4c4624154cb867d
Author: lacatoire <la.catoire@gmail.com>
Date: Fri Oct 16 16:48:45 2026 +0200
ext/snmp: Copy the context name in SNMP::setSecurity()
SNMP::setSecurity() stored a pointer into the $contextName string instead of
copying it, so the next request read freed memory once the string was
released. Copy it and free it with the session.
Close GH-25205
diff --git a/NEWS b/NEWS
index a6a04bdbf15..004580cf218 100644
--- a/NEWS
+++ b/NEWS
@@ -82,6 +82,10 @@ PHP NEWS
. Fixed stack buffer overflow with long connection user names, passwords,
charsets, or roles. (Ilia Alshanetsky)
+- SNMP:
+ . Fixed use-after-free of the context name set by SNMP::setSecurity().
+ (lacatoire)
+
- SOAP:
. Fixed bug GH-25267 (NULL dereference in to_xml_any() with integer key).
(lazerg)
diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c
index 6277c1f3f72..bfc7131e742 100644
--- a/ext/snmp/snmp.c
+++ b/ext/snmp/snmp.c
@@ -160,6 +160,7 @@ static void netsnmp_session_free(php_snmp_session **session) /* {{{ */
PHP_SNMP_SESSION_FREE(community);
PHP_SNMP_SESSION_FREE(securityName);
PHP_SNMP_SESSION_FREE(contextEngineID);
+ PHP_SNMP_SESSION_FREE(contextName);
efree(*session);
*session = NULL;
}
@@ -1169,7 +1170,10 @@ static ZEND_ATTRIBUTE_NONNULL_ARGS(2) bool netsnmp_session_set_security(struct s
/* Setting contextName if specified */
if (contextName) {
- session->contextName = ZSTR_VAL(contextName);
+ if (session->contextName) {
+ efree(session->contextName);
+ }
+ session->contextName = estrndup(ZSTR_VAL(contextName), ZSTR_LEN(contextName));
session->contextNameLen = ZSTR_LEN(contextName);
}
diff --git a/ext/snmp/tests/snmp-object-setSecurity-contextName.phpt b/ext/snmp/tests/snmp-object-setSecurity-contextName.phpt
new file mode 100644
index 00000000000..95055e2be8f
--- /dev/null
+++ b/ext/snmp/tests/snmp-object-setSecurity-contextName.phpt
@@ -0,0 +1,22 @@
+--TEST--
+SNMP::setSecurity() - the context name is copied
+--EXTENSIONS--
+snmp
+--SKIPIF--
+<?php
+require_once(__DIR__.'/skipif.inc');
+?>
+--FILE--
+<?php
+require_once(__DIR__.'/snmp_include.inc');
+
+$session = new SNMP(SNMP::VERSION_3, $hostname, $rwuser, $timeout, $retries);
+$context = str_repeat('c', 5) . random_int(10, 99);
+$session->setSecurity('authPriv', 'MD5', $auth_pass, 'AES', $priv_pass, $context);
+unset($context);
+// The agent does not know this context, only the lifetime of the name matters.
+var_dump(@$session->get('.1.3.6.1.2.1.1.1.0'));
+$session->close();
+?>
+--EXPECT--
+bool(false)