Skip to content

Commit 6191e3a

Browse files
committed
ext/mysqlnd: Fix persistent free of non-persistent connect_attr key.
set_client_option_2d() built the temporary key string with the connection's persistent flag but always released it with persistent=1. On a duplicate-key update of the connect_attr hash, zend_hash_update() does not retain the passed key, so the caller-owned non-persistent string was freed via free() instead of efree(), tripping the IS_STR_PERSISTENT assertion in debug builds and mismatching allocators in release. Reachable by retrying mysqli_real_connect() on a handle whose first connect failed, since mysqlnd re-adds _client_name and _server_host on every connect attempt.
1 parent 5bd7e3b commit 6191e3a

1 file changed

Lines changed: 2 additions & 3 deletions

File tree

ext/mysqlnd/mysqlnd_connection.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1572,17 +1572,16 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option_2d)(MYSQLND_CONN_DATA * cons
15721572
zval attrz;
15731573
zend_string *str;
15741574

1575+
str = zend_string_init(key, strlen(key), conn->persistent);
15751576
if (conn->persistent) {
1576-
str = zend_string_init(key, strlen(key), 1);
15771577
GC_MAKE_PERSISTENT_LOCAL(str);
15781578
ZVAL_NEW_STR(&attrz, zend_string_init(value, strlen(value), 1));
15791579
GC_MAKE_PERSISTENT_LOCAL(Z_COUNTED(attrz));
15801580
} else {
1581-
str = zend_string_init(key, strlen(key), 0);
15821581
ZVAL_NEW_STR(&attrz, zend_string_init(value, strlen(value), 0));
15831582
}
15841583
zend_hash_update(conn->options->connect_attr, str, &attrz);
1585-
zend_string_release_ex(str, 1);
1584+
zend_string_release_ex(str, conn->persistent);
15861585
}
15871586
break;
15881587
default:

0 commit comments

Comments
 (0)