diff --git a/NEWS b/NEWS index 5607f31081b8..531a17d750c5 100644 --- a/NEWS +++ b/NEWS @@ -45,6 +45,10 @@ PHP NEWS . Fixed a leak when a persistent connection failed a liveness check with no other live PDO handle. (iliaal) +- SNMP: + . Fixed bug GH-23453 (SNMP::setSecurity() frees a non-malloced address with a + context engine ID longer than 32 bytes). (Lazizbek Ergashev) + - Standard: . Fixed a memory leak in array_merge_recursive() when the recursive merge of an object converted to an array fails. (David Carlier) diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c index afbdda285ec4..6277c1f3f728 100644 --- a/ext/snmp/snmp.c +++ b/ext/snmp/snmp.c @@ -1086,7 +1086,8 @@ static bool netsnmp_session_set_contextEngineID(struct snmp_session *s, zend_str size_t ebuf_len = 32, eout_len = 0; uint8_t *ebuf = (uint8_t *) emalloc(ebuf_len); - if (!snmp_hex_to_binary(&ebuf, &ebuf_len, &eout_len, 1, ZSTR_VAL(contextEngineID))) { + /* Disallow reallocation: ebuf comes from emalloc() and net-snmp would realloc() it. */ + if (!snmp_hex_to_binary(&ebuf, &ebuf_len, &eout_len, 0, ZSTR_VAL(contextEngineID))) { // TODO Promote to Error? php_error_docref(NULL, E_WARNING, "Bad engine ID value '%s'", ZSTR_VAL(contextEngineID)); efree(ebuf); diff --git a/ext/snmp/tests/gh23453.phpt b/ext/snmp/tests/gh23453.phpt new file mode 100644 index 000000000000..aaa89baad182 --- /dev/null +++ b/ext/snmp/tests/gh23453.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-23453 (SNMP::setSecurity() frees a non-malloced address with a context engine ID longer than 32 bytes) +--EXTENSIONS-- +snmp +--FILE-- +setSecurity('authPriv', 'SHA', 'authpassword12345', 'AES', 'privpassword12345', 'myContext', str_repeat('aa', 32))); +var_dump($session->setSecurity('authPriv', 'SHA', 'authpassword12345', 'AES', 'privpassword12345', 'myContext', str_repeat('aa', 33))); +?> +--EXPECTF-- +bool(true) + +Warning: SNMP::setSecurity(): Bad engine ID value 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' in %s on line %d +bool(false)