From 41564acaaccbd0bc68ae5ddd5c7e80bbb6667fb8 Mon Sep 17 00:00:00 2001 From: Rene Cannao Date: Mon, 9 Feb 2026 13:07:53 +0000 Subject: [PATCH] Fix #5355: Add null pointer check in RequestEnd() to prevent use-after-free crash This commit addresses a use-after-free race condition that could cause ProxySQL to crash with SIGSEGV during COM_CHANGE_USER timeout scenarios. Root Cause: ----------- When a session is in RESETTING_CONNECTION status and the backend times out during COM_CHANGE_USER, the code calls RequestEnd() to handle the error. However, RequestEnd() accesses client_myds without null checks. If the session is marked as unhealthy and deleted by ProcessAllSessions_Healthy0() while RequestEnd() is still executing, this results in a use-after-free crash. The crash is particularly likely during AWS Aurora failures when: 1. Monitor detects Aurora master timeouts 2. Multiple sessions experience connection issues 3. Many client connections are marked unhealthy 4. The high volume of session deletions increases race condition probability Fix: ---- Added a null pointer check before accessing client_myds in the unexp_com_pings handling code within RequestEnd(). This is a defensive programming fix that prevents the crash when client_myds has been freed. A more robust fix would involve proper session lifecycle management with reference counting. Fixes: #5355 --- lib/MySQL_Session.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 3525aa9c8..31385f723 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -8883,7 +8883,9 @@ void MySQL_Session::RequestEnd(MySQL_Data_Stream *myds,const unsigned int myerrn // @note This is a "temporary" solution that should be removed if packet queueing is implemented, since // it will make the 'unexp_com_pings' field obsolete. /////////////////////////////////////////////////////////////////////////////////////////////// - if (client_myds->unexp_com_pings) { + // Fix #5355: Add null pointer check for client_myds to prevent use-after-free crash + // when session is deleted while RequestEnd() is still executing (e.g., during COM_CHANGE_USER timeout) + if (client_myds && client_myds->unexp_com_pings) { client_myds->setDSS_STATE_QUERY_SENT_NET(); if (client_myds->unexp_com_pings) {