Commit:    ed6763420c10c5eb47d6db675322ecaa6de079b6
Author:    Boris Lytochkin <lytbo...@php.net>         Thu, 7 Feb 2013 14:48:28 
+0400
Parents:   702b436ef470cc02f8e2cc21f2fadeee42103c74
Branches:  master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=ed6763420c10c5eb47d6db675322ecaa6de079b6

Log:
fix bug #64124 (IPv6 malformed)

hostname returned from zend_parse_parameters() was modified in
netsnmp_session_init() that caused imput parameter modification along with
unpredictable changes when parameter is a constant sctring.

One typo in comment was fixed.

Bugs:
https://bugs.php.net/64124

Changed paths:
  M  ext/snmp/snmp.c
  A  ext/snmp/tests/bug64124.phpt


Diff:
diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c
index 037fcce..a3bd44c 100644
--- a/ext/snmp/snmp.c
+++ b/ext/snmp/snmp.c
@@ -1096,8 +1096,7 @@ static int php_snmp_parse_oid(zval *object, int st, 
struct objid_query *objid_qu
 static int netsnmp_session_init(php_snmp_session **session_p, int version, 
char *hostname, char *community, int timeout, int retries TSRMLS_DC)
 {
        php_snmp_session *session;
-       char *pptr;
-       char buf[MAX_NAME_LEN];
+       char *pptr, *host_ptr;
        int force_ipv6 = FALSE;
        int n;
        struct sockaddr **psal;
@@ -1111,8 +1110,6 @@ static int netsnmp_session_init(php_snmp_session 
**session_p, int version, char
        }
        memset(session, 0, sizeof(php_snmp_session));
 
-       strlcpy(buf, hostname, sizeof(buf));
-
        snmp_sess_init(session);
 
        session->version = version;
@@ -1123,13 +1120,15 @@ static int netsnmp_session_init(php_snmp_session 
**session_p, int version, char
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "emalloc() failed 
while copying hostname");
                return (-1);
        }
-       *(session->peername) = '\0';
+       /* we copy original hostname for further processing */
+       strlcpy(session->peername, hostname, MAX_NAME_LEN);
+       host_ptr = session->peername;
 
        /* Reading the hostname and its optional non-default port number */
-       if (*hostname == '[') { /* IPv6 address */
+       if (*host_ptr == '[') { /* IPv6 address */
                force_ipv6 = TRUE;
-               hostname++;
-               if ((pptr = strchr(hostname, ']'))) {
+               host_ptr++;
+               if ((pptr = strchr(host_ptr, ']'))) {
                        if (pptr[1] == ':') {
                                session->remote_port = atoi(pptr + 2);
                        }
@@ -1139,7 +1138,7 @@ static int netsnmp_session_init(php_snmp_session 
**session_p, int version, char
                        return (-1);
                }
        } else { /* IPv4 address */
-               if ((pptr = strchr(hostname, ':'))) {
+               if ((pptr = strchr(host_ptr, ':'))) {
                        session->remote_port = atoi(pptr + 1);
                        *pptr = '\0';
                }
@@ -1147,11 +1146,13 @@ static int netsnmp_session_init(php_snmp_session 
**session_p, int version, char
 
        /* since Net-SNMP library requires 'udp6:' prefix for all IPv6 
addresses (in FQDN form too) we need to
           perform possible name resolution before running any SNMP queries */
-       if ((n = php_network_getaddresses(hostname, SOCK_DGRAM, &psal, NULL 
TSRMLS_CC)) == 0) { /* some resover error */
+       if ((n = php_network_getaddresses(host_ptr, SOCK_DGRAM, &psal, NULL 
TSRMLS_CC)) == 0) { /* some resolver error */
                /* warnings sent, bailing out */
                return (-1);
        }
 
+       /* we have everything we need in psal, flush peername and fill it 
properly */
+       *(session->peername) = '\0';
        res = psal;
        while (n-- > 0) {
                pptr = session->peername;
@@ -1181,7 +1182,7 @@ static int netsnmp_session_init(php_snmp_session 
**session_p, int version, char
        }
 
        if (strlen(session->peername) == 0) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown failure 
while resolving '%s'", buf);
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown failure 
while resolving '%s'", hostname);
                return (-1);
        }
        /* XXX FIXME
diff --git a/ext/snmp/tests/bug64124.phpt b/ext/snmp/tests/bug64124.phpt
new file mode 100644
index 0000000..454b06d
--- /dev/null
+++ b/ext/snmp/tests/bug64124.phpt
@@ -0,0 +1,40 @@
+--TEST--                                 
+Bug #64124 IPv6 malformed
+--CREDITS--
+Boris Lytochkin
+--SKIPIF--
+<?php
+require_once(dirname(__FILE__).'/skipif.inc');
+
+$packed = str_repeat(chr(0), 15) . chr(1);
+if (@inet_ntop($packed) === false) {
+       die("skip no IPv6 support");
+}
+?>
+--FILE--
+<?php
+require_once(dirname(__FILE__).'/snmp_include.inc');
+
+# hostname variable was modified inline in netsnmp_session_init()
+# Should be checked with IPv6 since IPv4 processing code do not alter pointer 
position
+
+//EXPECTF format is quickprint OFF
+snmp_set_quick_print(false);
+snmp_set_valueretrieval(SNMP_VALUE_PLAIN);
+
+$checkvar = "$hostname6_port";
+
+var_dump(snmpget($checkvar, $community, '.1.3.6.1.2.1.1.1.0'));
+var_dump(($checkvar === $hostname6_port));
+var_dump(snmpget($checkvar, $community, '.1.3.6.1.2.1.1.1.0'));
+var_dump(($checkvar === $hostname6_port));
+var_dump(snmpget($checkvar, $community, '.1.3.6.1.2.1.1.1.0'));
+var_dump(($checkvar === $hostname6_port));
+?>
+--EXPECTF--
+%unicode|string%(%d) "%s"
+bool(true)
+%unicode|string%(%d) "%s"
+bool(true)
+%unicode|string%(%d) "%s"
+bool(true)


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to