summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2015-07-05 00:00:53 -0700
committerStanislav Malyshev <stas@php.net>2015-07-05 00:00:53 -0700
commita46bae2df257ec9bbc601204c73a8f7b103edee1 (patch)
tree3b9bc4e45baab7325a0f4004441022756ab72b9e
parent3e88d610e54dac75a374af9e8501f02da67e4466 (diff)
downloadphp-git-a46bae2df257ec9bbc601204c73a8f7b103edee1.tar.gz
Fix bug #69669 (mysqlnd is vulnerable to BACKRONYM)
-rw-r--r--ext/mysqlnd/mysqlnd.c67
1 files changed, 42 insertions, 25 deletions
diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c
index d265dfd392..1c4a7714cc 100644
--- a/ext/mysqlnd/mysqlnd.c
+++ b/ext/mysqlnd/mysqlnd.c
@@ -378,7 +378,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_server_option)(MYSQLND_CONN_DATA * const c
int2store(buffer, (unsigned int) option);
ret = conn->m->simple_command(conn, COM_SET_OPTION, buffer, sizeof(buffer), PROT_EOF_PACKET, FALSE, TRUE TSRMLS_CC);
-
+
conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
}
DBG_RETURN(ret);
@@ -446,26 +446,43 @@ mysqlnd_switch_to_ssl_if_needed(
}
#ifdef MYSQLND_SSL_SUPPORTED
- if ((greet_packet->server_capabilities & CLIENT_SSL) && (mysql_flags & CLIENT_SSL)) {
- zend_bool verify = mysql_flags & CLIENT_SSL_VERIFY_SERVER_CERT? TRUE:FALSE;
- DBG_INF("Switching to SSL");
- if (!PACKET_WRITE(auth_packet, conn)) {
- CONN_SET_STATE(conn, CONN_QUIT_SENT);
- SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
- goto end;
- }
+ if (mysql_flags & CLIENT_SSL) {
+ zend_bool server_has_ssl = (greet_packet->server_capabilities & CLIENT_SSL)? TRUE:FALSE;
+ if (server_has_ssl == FALSE) {
+ goto close_conn;
+ } else {
+ zend_bool verify = mysql_flags & CLIENT_SSL_VERIFY_SERVER_CERT? TRUE:FALSE;
+ DBG_INF("Switching to SSL");
+ if (!PACKET_WRITE(auth_packet, conn)) {
+ CONN_SET_STATE(conn, CONN_QUIT_SENT);
+ SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
+ goto end;
+ }
- conn->net->m.set_client_option(conn->net, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (const char *) &verify TSRMLS_CC);
+ conn->net->m.set_client_option(conn->net, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (const char *) &verify TSRMLS_CC);
- if (FAIL == conn->net->m.enable_ssl(conn->net TSRMLS_CC)) {
- goto end;
+ if (FAIL == conn->net->m.enable_ssl(conn->net TSRMLS_CC)) {
+ goto end;
+ }
}
}
+#else
+ auth_packet->client_flags &= ~CLIENT_SSL;
+ if (!PACKET_WRITE(auth_packet, conn)) {
+ goto close_conn;
+ }
#endif
ret = PASS;
end:
PACKET_FREE(auth_packet);
DBG_RETURN(ret);
+
+close_conn:
+ CONN_SET_STATE(conn, CONN_QUIT_SENT);
+ conn->m->send_close(conn);
+ SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
+ PACKET_FREE(auth_packet);
+ DBG_RETURN(ret);
}
/* }}} */
@@ -587,7 +604,7 @@ mysqlnd_connect_run_authentication(
if (plugin_data) {
mnd_efree(plugin_data);
}
-
+
if (ret == PASS) {
DBG_INF_FMT("saving requested_protocol=%s", requested_protocol);
conn->m->set_client_option(conn, MYSQLND_OPT_AUTH_PROTOCOL, requested_protocol TSRMLS_CC);
@@ -1438,7 +1455,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, sqlstate)(const MYSQLND_CONN_DATA * const conn
/* {{{ mysqlnd_old_escape_string */
-PHPAPI ulong
+PHPAPI ulong
mysqlnd_old_escape_string(char * newstr, const char * escapestr, size_t escapestr_len TSRMLS_DC)
{
DBG_ENTER("mysqlnd_old_escape_string");
@@ -1599,7 +1616,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, statistic)(MYSQLND_CONN_DATA * conn, char **me
if (PASS == (ret = PACKET_READ(stats_header, conn))) {
/* will be freed by Zend, thus don't use the mnd_ allocator */
- *message = estrndup(stats_header->message, stats_header->message_len);
+ *message = estrndup(stats_header->message, stats_header->message_len);
*message_len = stats_header->message_len;
DBG_INF(*message);
}
@@ -1724,7 +1741,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, shutdown)(MYSQLND_CONN_DATA * const conn, uint
conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
}
- DBG_RETURN(ret);
+ DBG_RETURN(ret);
}
/* }}} */
@@ -2243,7 +2260,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, change_user)(MYSQLND_CONN_DATA * const conn,
*/
end:
if (TRUE == local_tx_started) {
- conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
+ conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
}
DBG_INF(ret == PASS? "PASS":"FAIL");
DBG_RETURN(ret);
@@ -2335,7 +2352,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option)(MYSQLND_CONN_DATA * const c
ret = FAIL;
break;
}
-
+
new_charset_name = mnd_pestrdup(value, conn->persistent);
if (!new_charset_name) {
goto oom;
@@ -2401,11 +2418,11 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option)(MYSQLND_CONN_DATA * const c
default:
ret = FAIL;
}
- conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
+ conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
DBG_RETURN(ret);
oom:
SET_OOM_ERROR(*conn->error_info);
- conn->m->local_tx_end(conn, this_func, FAIL TSRMLS_CC);
+ conn->m->local_tx_end(conn, this_func, FAIL TSRMLS_CC);
end:
DBG_RETURN(FAIL);
}
@@ -2446,7 +2463,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, use_result)(MYSQLND_CONN_DATA * const conn TSR
conn->current_result = NULL;
} while (0);
- conn->m->local_tx_end(conn, this_func, result == NULL? FAIL:PASS TSRMLS_CC);
+ conn->m->local_tx_end(conn, this_func, result == NULL? FAIL:PASS TSRMLS_CC);
}
DBG_RETURN(result);
@@ -2486,7 +2503,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, store_result)(MYSQLND_CONN_DATA * const conn T
conn->current_result = NULL;
} while (0);
- conn->m->local_tx_end(conn, this_func, result == NULL? FAIL:PASS TSRMLS_CC);
+ conn->m->local_tx_end(conn, this_func, result == NULL? FAIL:PASS TSRMLS_CC);
}
DBG_RETURN(result);
}
@@ -2515,7 +2532,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_autocommit)(MYSQLND_CONN_DATA * conn, unsi
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
ret = conn->m->query(conn, (mode) ? "SET AUTOCOMMIT=1":"SET AUTOCOMMIT=0", sizeof("SET AUTOCOMMIT=1") - 1 TSRMLS_CC);
- conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
+ conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
}
DBG_RETURN(ret);
@@ -2533,7 +2550,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_commit)(MYSQLND_CONN_DATA * conn TSRMLS_DC)
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
ret = conn->m->query(conn, "COMMIT", sizeof("COMMIT") - 1 TSRMLS_CC);
- conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
+ conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
}
DBG_RETURN(ret);
@@ -2551,7 +2568,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_rollback)(MYSQLND_CONN_DATA * conn TSRMLS_D
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
ret = conn->m->query(conn, "ROLLBACK", sizeof("ROLLBACK") - 1 TSRMLS_CC);
- conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
+ conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
}
DBG_RETURN(ret);