From 06b87f912b4f896e53d82c4d14b76a036903e08d Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 21 Mar 2024 23:51:44 +0100 Subject: [PATCH] Remove broken hack in mysqlnd_vio::close_stream What happens is that the persistent network stream resource gets freed, yet stays inside EG(persistent_list). This causes a crash on shutdown when the persistent list is getting cleared, as the engine will try to free the network stream again. The code in close_stream gets confused between persistent vs non-persistent allocations when EG(active) is false. This code was introduced in c3019a1 to fix crashes when the persistent list gets destroyed before module shutdown is called. This is indeed a potential problem that was fixed on the master branch in 5941cda. This fixes the crash reason of GH-10599. --- ext/mysqlnd/mysqlnd_vio.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/ext/mysqlnd/mysqlnd_vio.c b/ext/mysqlnd/mysqlnd_vio.c index 312bf7e2782..c12317c4366 100644 --- a/ext/mysqlnd/mysqlnd_vio.c +++ b/ext/mysqlnd/mysqlnd_vio.c @@ -652,15 +652,11 @@ MYSQLND_METHOD(mysqlnd_vio, close_stream)(MYSQLND_VIO * const net, MYSQLND_STATS bool pers = net->persistent; DBG_INF_FMT("Freeing stream. abstract=%p", net_stream->abstract); /* We removed the resource from the stream, so pass FREE_RSRC_DTOR now to force - * destruction to occur during shutdown, because it won't happen through the resource. */ - /* TODO: The EG(active) check here is dead -- check IN_SHUTDOWN? */ - if (pers && EG(active)) { + * destruction to occur during shutdown, because it won't happen through the resource + * because we removed the resource from the EG resource list(s). */ + if (pers) { php_stream_free(net_stream, PHP_STREAM_FREE_CLOSE_PERSISTENT | PHP_STREAM_FREE_RSRC_DTOR); } else { - /* - otherwise we will crash because the EG(persistent_list) has been freed already, - before the modules are shut down - */ php_stream_free(net_stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR); } net->data->m.set_stream(net, NULL);