Skip to content

Commit 39f1ed4

Browse files
committed
Merge branch 'PHP-8.5'
* PHP-8.5: Fix GH-21336: undefined behavior in snmp setSecurity.
2 parents c506142 + d08d80c commit 39f1ed4

File tree

2 files changed

+72
-8
lines changed

2 files changed

+72
-8
lines changed

ext/snmp/snmp.c

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,7 @@ static bool snmp_session_set_sec_level(struct snmp_session *s, zend_string *leve
10051005
/* }}} */
10061006

10071007
/* {{{ Set the authentication protocol in the snmpv3 session */
1008-
static bool snmp_session_set_auth_protocol(struct snmp_session *s, zend_string *prot)
1008+
static ZEND_ATTRIBUTE_NONNULL bool snmp_session_set_auth_protocol(struct snmp_session *s, zend_string *prot)
10091009
{
10101010
#ifndef DISABLE_MD5
10111011
if (zend_string_equals_literal_ci(prot, "MD5")) {
@@ -1054,7 +1054,7 @@ static bool snmp_session_set_auth_protocol(struct snmp_session *s, zend_string *
10541054
/* }}} */
10551055

10561056
/* {{{ Set the security protocol in the snmpv3 session */
1057-
static bool snmp_session_set_sec_protocol(struct snmp_session *s, zend_string *prot)
1057+
static ZEND_ATTRIBUTE_NONNULL bool snmp_session_set_sec_protocol(struct snmp_session *s, zend_string *prot)
10581058
{
10591059
#ifndef NETSNMP_DISABLE_DES
10601060
if (zend_string_equals_literal_ci(prot, "DES")) {
@@ -1091,9 +1091,10 @@ static bool snmp_session_set_sec_protocol(struct snmp_session *s, zend_string *p
10911091
/* }}} */
10921092

10931093
/* {{{ Make key from pass phrase in the snmpv3 session */
1094-
static bool snmp_session_gen_auth_key(struct snmp_session *s, zend_string *pass)
1094+
static ZEND_ATTRIBUTE_NONNULL bool snmp_session_gen_auth_key(struct snmp_session *s, zend_string *pass)
10951095
{
10961096
int snmp_errno;
1097+
10971098
s->securityAuthKeyLen = USM_AUTH_KU_LEN;
10981099
if ((snmp_errno = generate_Ku(s->securityAuthProto, s->securityAuthProtoLen,
10991100
(uint8_t *) ZSTR_VAL(pass), ZSTR_LEN(pass),
@@ -1106,7 +1107,7 @@ static bool snmp_session_gen_auth_key(struct snmp_session *s, zend_string *pass)
11061107
/* }}} */
11071108

11081109
/* {{{ Make key from pass phrase in the snmpv3 session */
1109-
static bool snmp_session_gen_sec_key(struct snmp_session *s, zend_string *pass)
1110+
static ZEND_ATTRIBUTE_NONNULL bool snmp_session_gen_sec_key(struct snmp_session *s, zend_string *pass)
11101111
{
11111112
int snmp_errno;
11121113

@@ -1145,9 +1146,10 @@ static bool snmp_session_set_contextEngineID(struct snmp_session *s, zend_string
11451146
/* }}} */
11461147

11471148
/* {{{ Set all snmpv3-related security options */
1148-
static bool snmp_session_set_security(struct snmp_session *session, zend_string *sec_level,
1149+
static ZEND_ATTRIBUTE_NONNULL_ARGS(2) bool snmp_session_set_security(struct snmp_session *session, zend_string *sec_level,
11491150
zend_string *auth_protocol, zend_string *auth_passphrase, zend_string *priv_protocol,
1150-
zend_string *priv_passphrase, zend_string *contextName, zend_string *contextEngineID)
1151+
zend_string *priv_passphrase, zend_string *contextName, zend_string *contextEngineID,
1152+
uint32_t auth_protocol_argnum)
11511153
{
11521154

11531155
/* Setting the security level. */
@@ -1158,25 +1160,46 @@ static bool snmp_session_set_security(struct snmp_session *session, zend_string
11581160

11591161
if (session->securityLevel == SNMP_SEC_LEVEL_AUTHNOPRIV || session->securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) {
11601162

1163+
if (!auth_protocol) {
1164+
zend_argument_value_error(auth_protocol_argnum, "cannot be null when security level is \"authNoPriv\" or \"authPriv\"");
1165+
return false;
1166+
}
1167+
11611168
/* Setting the authentication protocol. */
11621169
if (!snmp_session_set_auth_protocol(session, auth_protocol)) {
11631170
/* ValueError already generated, just bail out */
11641171
return false;
11651172
}
11661173

1174+
if (!auth_passphrase) {
1175+
zend_argument_value_error(auth_protocol_argnum + 1, "cannot be null when security level is \"authNoPriv\" or \"authPriv\"");
1176+
return false;
1177+
}
1178+
11671179
/* Setting the authentication passphrase. */
11681180
if (!snmp_session_gen_auth_key(session, auth_passphrase)) {
11691181
/* Warning message sent already, just bail out */
11701182
return false;
11711183
}
11721184

11731185
if (session->securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) {
1186+
1187+
if (!priv_protocol) {
1188+
zend_argument_value_error(auth_protocol_argnum + 2, "cannot be null when security level is \"authPriv\"");
1189+
return false;
1190+
}
1191+
11741192
/* Setting the security protocol. */
11751193
if (!snmp_session_set_sec_protocol(session, priv_protocol)) {
11761194
/* ValueError already generated, just bail out */
11771195
return false;
11781196
}
11791197

1198+
if (!priv_passphrase) {
1199+
zend_argument_value_error(auth_protocol_argnum + 3, "cannot be null when security level is \"authPriv\"");
1200+
return false;
1201+
}
1202+
11801203
/* Setting the security protocol passphrase. */
11811204
if (!snmp_session_gen_sec_key(session, priv_passphrase)) {
11821205
/* Warning message sent already, just bail out */
@@ -1346,7 +1369,7 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
13461369
snmp_session_free(&session);
13471370
RETURN_FALSE;
13481371
}
1349-
if (version == SNMP_VERSION_3 && !snmp_session_set_security(session, a3, a4, a5, a6, a7, NULL, NULL)) {
1372+
if (version == SNMP_VERSION_3 && !snmp_session_set_security(session, a3, a4, a5, a6, a7, NULL, NULL, 4)) {
13501373
php_free_objid_query(&objid_query, oid_ht, value_ht, st);
13511374
snmp_session_free(&session);
13521375
/* Warning message sent already, just bail out */
@@ -1721,7 +1744,7 @@ PHP_METHOD(SNMP, setSecurity)
17211744
RETURN_THROWS();
17221745
}
17231746

1724-
if (!snmp_session_set_security(snmp_object->session, a1, a2, a3, a4, a5, a6, a7)) {
1747+
if (!snmp_session_set_security(snmp_object->session, a1, a2, a3, a4, a5, a6, a7, 2)) {
17251748
/* Warning message sent already, just bail out */
17261749
RETURN_FALSE;
17271750
}

ext/snmp/tests/gh21336.phpt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
GH-21336 (undefined behavior in snmp - NULL pointer dereference in setSecurity)
3+
--EXTENSIONS--
4+
snmp
5+
--FILE--
6+
<?php
7+
$session = new SNMP(SNMP::VERSION_3, 'localhost', 'user');
8+
9+
// auth protocol NULL
10+
try {
11+
$session->setSecurity('authPriv');
12+
} catch (ValueError $e) {
13+
echo $e->getMessage() . PHP_EOL;
14+
}
15+
16+
// auth passphrase NULL
17+
try {
18+
$session->setSecurity('authNoPriv', 'MD5');
19+
} catch (ValueError $e) {
20+
echo $e->getMessage() . PHP_EOL;
21+
}
22+
23+
// priv protocol NULL
24+
try {
25+
$session->setSecurity('authPriv', 'MD5', 'test12345');
26+
} catch (ValueError $e) {
27+
echo $e->getMessage() . PHP_EOL;
28+
}
29+
30+
// priv passphrase NULL
31+
try {
32+
$session->setSecurity('authPriv', 'MD5', 'test12345', 'AES');
33+
} catch (ValueError $e) {
34+
echo $e->getMessage() . PHP_EOL;
35+
}
36+
?>
37+
--EXPECT--
38+
SNMP::setSecurity(): Argument #2 ($authProtocol) cannot be null when security level is "authNoPriv" or "authPriv"
39+
SNMP::setSecurity(): Argument #3 ($authPassphrase) cannot be null when security level is "authNoPriv" or "authPriv"
40+
SNMP::setSecurity(): Argument #4 ($privacyProtocol) cannot be null when security level is "authPriv"
41+
SNMP::setSecurity(): Argument #5 ($privacyPassphrase) cannot be null when security level is "authPriv"

0 commit comments

Comments
 (0)