Skip to content

Conversation

@renecannao
Copy link
Contributor

@renecannao renecannao commented Feb 9, 2026

Summary

This PR fixes a use-after-free race condition that causes ProxySQL to crash with SIGSEGV during COM_CHANGE_USER timeout scenarios.

Issue

Fixes #5355

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 at:

const string cli_addr { get_client_addr(this->client_myds->client_addr) };

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():

-	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) {

This is a defensive programming fix that prevents the crash when client_myds has been freed.

Test plan

  • Code compiles successfully
  • Testing with Aurora failover scenario would be beneficial to verify the fix

Related

See issue #5355 for detailed root cause analysis and alternative solution approaches.

Summary by CodeRabbit

  • Bug Fixes
    • Improved session stability to prevent potential crashes during session termination.

…r-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
@gemini-code-assist
Copy link

Summary of Changes

Hello @renecannao, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly improves the stability of ProxySQL by resolving a critical use-after-free vulnerability. The change prevents crashes that could occur when handling COM_CHANGE_USER timeouts, particularly in environments with high session churn or during database failovers. By implementing a defensive null pointer check, the system is made more robust against race conditions involving session deallocation.

Highlights

  • Critical Bug Fix: This pull request addresses and fixes a use-after-free race condition that could lead to ProxySQL crashing with a SIGSEGV, particularly during COM_CHANGE_USER timeout scenarios.
  • Null Pointer Check: A null pointer check has been added for client_myds within the RequestEnd() function. This prevents dereferencing a freed pointer if the session is deleted concurrently while RequestEnd() is still executing.
  • Improved Stability: The fix enhances the stability of ProxySQL, especially under high-concurrency conditions and during AWS Aurora failovers where multiple sessions might be marked unhealthy and deleted.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • lib/MySQL_Session.cpp
    • Added a null pointer check for client_myds before accessing its unexp_com_pings member in the RequestEnd() method to prevent a use-after-free crash.
Activity
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link

coderabbitai bot commented Feb 9, 2026

📝 Walkthrough

Walkthrough

A null pointer guard was added in MySQL_Session::RequestEnd to prevent use-after-free dereferencing when client_myds is invalid. The condition now checks if (client_myds && client_myds->unexp_com_pings) instead of directly accessing client_myds->unexp_com_pings.

Changes

Cohort / File(s) Summary
Null pointer validation
lib/MySQL_Session.cpp
Added defensive null pointer check for client_myds in RequestEnd function to guard against use-after-free when session is deleted during execution; includes explanatory comments.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

Suggested labels

status/triage

Poem

🐰 A pointer was wild, uncheck'd and untamed,
Dereferencing null—oh, what crash and what shame!
But now with a guard, before taking a peek,
The code stays alive, both robust and sleek! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically describes the main change: adding a null pointer check in RequestEnd() to prevent use-after-free crashes, directly addressing issue #5355.
Linked Issues check ✅ Passed The code change directly implements the required fix from issue #5355 by adding the null pointer check (client_myds &&) before dereferencing client_myds in the unexp_com_pings handling path, addressing the root cause of the SIGSEGV crash.
Out of Scope Changes check ✅ Passed The change is narrowly focused on the specific issue: only 3 lines added/1 removed in MySQL_Session.cpp with a defensive null check, containing no unrelated modifications or scope creep.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch v3.0-5355

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Feb 9, 2026

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request aims to fix a use-after-free crash by adding a null pointer check for client_myds. While the intention is correct, the current implementation is not sufficient to fully prevent the race condition described. The client_myds pointer can become invalid at any point during the execution of the if block, not just at the entry. I've added a comment explaining why the fix is incomplete and suggesting a more robust approach.

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) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

While adding a null check for client_myds is a good defensive measure, this fix is incomplete. The race condition described can invalidate client_myds at any point. After this check, client_myds is dereferenced multiple times inside the block (lines 8889, 8891, 8892, etc.) without further checks. If client_myds becomes null or a dangling pointer after this initial check, the program will still crash.

A truly safe fix would require a synchronization mechanism like a lock to protect access to the session and its members throughout this operation. Given the constraints, a more robust change would be to re-validate the client_myds pointer before each dereference inside this block.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lib/MySQL_Session.cpp (1)

8886-8892: ⚠️ Potential issue | 🟠 Major

Add proper synchronization to prevent use-after-free; null check alone is insufficient.

The null guard at line 8889 prevents NULL dereference but not UAF: client_myds can be freed and remain non-NULL between the check and the multiple subsequent dereferences (lines 8890–8912). Additionally, the destructor does not null the pointer after delete client_myds (line 798), leaving a dangling pointer. Implement either (a) mutual exclusion preventing session deletion during RequestEnd, or (b) reference counting or lifetime tracking to serialize or safely defer deletion until RequestEnd completes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proxysql service crash/restart when monitor get aws aurora auto-discovered master endpoint failures

1 participant