Skip to content

MDEV-33843: Server crash via XPath unary minus recursion - #6051

Open
dfengliu wants to merge 1 commit into
MariaDB:mainfrom
dfengliu:mdev-33843-xpath-unary-stack-check
Open

dfengliu wants to merge 1 commit into
MariaDB:mainfrom
dfengliu:mdev-33843-xpath-unary-stack-check

Conversation

@dfengliu

@dfengliu dfengliu commented Nov 2, 2026

Copy link
Copy Markdown

Problem

MDEV-33843 added a check_stack_overrun() guard to my_xpath_parse_OrExpr(), but the XPath rule UnaryExpr ::= '-' UnaryExpr recurses directly in my_xpath_parse_UnaryExpr(). A path argument made of many consecutive - tokens therefore bypasses the guard and exhausts the backend thread stack.

Reproducer

SELECT UPDATEXML(NULL, REPEAT('-', 100000), 1);

Before the patch the backend crashes (SIGSEGV, exit 139) and the client reports ERROR 2013 (HY000): Lost connection to server during query. REPEAT('(', 100000) is already handled correctly, which shows the missing guard is specific to the unary-minus recursion.

Fix

Add the same check_stack_overrun(xpath->thd, STACK_MIN_SIZE, NULL) check at the entry of my_xpath_parse_UnaryExpr(), so every recursive call is bounded.

After the patch the statement returns the controlled ER_STACK_OVERRUN_NEED_MORE error and mariadbd keeps running.

Tests

New case in mysql-test/main/xml.test; main.xml passes. Without the patch the same test kills the server, so it fails without the fix.

This is a follow-up to MDEV-33843 (commit 7811201). Happy to file a separate MDEV if preferred.

Analysis:
The stack overrun check added by MDEV-33843 is executed only in
my_xpath_parse_OrExpr(). The XPath grammar rule

  UnaryExpr ::= '-' UnaryExpr

recurses directly in my_xpath_parse_UnaryExpr(), so a path made of many
'-' tokens consumes one stack frame per token without any limit and
overruns the thread stack. UPDATEXML() and EXTRACTVALUE() parse the path
in fix_fields(), therefore any user who can run a SELECT can terminate
the server with

  SELECT UPDATEXML(NULL, REPEAT('-', 100000), 1);

Before this patch the statement makes the backend exit with SIGSEGV
(exit status 139) and the client reports "Lost connection to server
during query". The equivalent parenthesized expression is already
rejected with ER_STACK_OVERRUN_NEED_MORE because it re-enters
my_xpath_parse_OrExpr().

Fix:
Run check_stack_overrun() at the entry of my_xpath_parse_UnaryExpr(),
as my_xpath_parse_OrExpr() does, and add a regression case to
mysql-test/main/xml that expects ER_STACK_OVERRUN_NEED_MORE.

The same statement then returns the regular stack-overrun error and the
server stays alive. main.xml passes.
@CLAassistant

CLAassistant commented Nov 2, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@gkodinov gkodinov added the External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements. label Nov 2, 2026

@gkodinov gkodinov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you for your contribution! This is a preliminary review.

LGTM! A very good analysis!

I'd say let's please file a separate jira: it's a different code path. But I'll leave this to the final reviewer to decide.

Please stay tuned for the final review.

@vuvova

vuvova commented Nov 2, 2026

Copy link
Copy Markdown
Member

and please rebase it onto 10.11, that's where the first fix was

@mariadb-RuchaDeodhar

Copy link
Copy Markdown
Contributor

looks ok. thank you!

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

Labels

External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements.

Development

Successfully merging this pull request may close these issues.

5 participants