From e05c3a5a37cec5f39148bd1fa893f8b3a1bf9161 Mon Sep 17 00:00:00 2001
From: Sutou Kouhei <kou@clear-code.com>
Date: Thu, 1 Oct 2026 18:16:14 +0900
Subject: [PATCH] MDEV-41285 ASAN heap-buffer-overflow
 mrn_get_string_between_quote/mrn_parse_table_param

`mrn_get_string_between_quote()` didn't advance `current_ptr` after it
processed an escape sequence such as `\x`. So it wrote the escaped
character repeatedly and overflowed the allocated buffer. It also
didn't terminate the extracted string with `\0` when the string had an
escape sequence.

For example, the following SQL caused a heap buffer overflow:

```sql
CREATE TABLE t1 (c INT) ENGINE=Mroonga COMMENT='engine "InnoDB\\x"';
```

This also returns `NULL` when `mrn_my_malloc()` fails.

Reported by Alice Sherepa. Found by Yuelin Wang.
---
 storage/mroonga/mrn_table.cpp                 |  5 +++
 .../r/create_table_comment_escape.result      | 15 ++++++++
 .../t/create_table_comment_escape.test        | 38 +++++++++++++++++++
 3 files changed, 58 insertions(+)
 create mode 100644 storage/mroonga/mysql-test/mroonga/storage/r/create_table_comment_escape.result
 create mode 100644 storage/mroonga/mysql-test/mroonga/storage/t/create_table_comment_escape.test

diff --git a/storage/mroonga/mrn_table.cpp b/storage/mroonga/mrn_table.cpp
index c3b8d091ca9..ca82e92ebfa 100644
--- a/storage/mroonga/mrn_table.cpp
+++ b/storage/mroonga/mrn_table.cpp
@@ -154,6 +154,9 @@ static char *mrn_get_string_between_quote(const char *ptr)
 
   size_t length = end_ptr - start_ptr;
   char *extracted_string = (char *)mrn_my_malloc(length + 1, MYF(MY_WME));
+  if (!extracted_string) {
+    DBUG_RETURN(NULL);
+  }
   if (esc_flg) {
     size_t extracted_index = 0;
     const char *current_ptr = start_ptr;
@@ -188,7 +191,9 @@ static char *mrn_get_string_between_quote(const char *ptr)
         break;
       }
       ++extracted_index;
+      current_ptr += 2;
     }
+    extracted_string[extracted_index] = '\0';
   } else {
     memcpy(extracted_string, start_ptr, length);
     extracted_string[length] = '\0';
diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_comment_escape.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_comment_escape.result
new file mode 100644
index 00000000000..9f1577d32e2
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_comment_escape.result
@@ -0,0 +1,15 @@
+CREATE TABLE tags (
+name VARCHAR(64) PRIMARY KEY
+) DEFAULT CHARSET=utf8mb4
+COLLATE=utf8mb4_bin
+COMMENT='default_tokenizer "Token\\Delimit"';
+SELECT mroonga_command("dump --dump_plugins no");
+mroonga_command("dump --dump_plugins no")
+table_create mroonga_operations TABLE_NO_KEY
+column_create mroonga_operations record COLUMN_SCALAR UInt32
+column_create mroonga_operations table COLUMN_SCALAR ShortText
+column_create mroonga_operations type COLUMN_SCALAR ShortText
+
+table_create tags TABLE_PAT_KEY ShortText --default_tokenizer TokenDelimit
+column_create tags name COLUMN_SCALAR ShortText
+DROP TABLE tags;
diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_comment_escape.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_comment_escape.test
new file mode 100644
index 00000000000..3cecb68806f
--- /dev/null
+++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_comment_escape.test
@@ -0,0 +1,38 @@
+# Copyright (C) 2026  Sutou Kouhei <kou@clear-code.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+--source ../../../../../include/mroonga/not_embedded.inc
+--source ../../../../../include/mroonga/have_mroonga.inc
+--source ../../../../../include/mroonga/load_mroonga_functions.inc
+
+--disable_query_log
+DROP DATABASE test;
+CREATE DATABASE test;
+USE test;
+--enable_query_log
+
+CREATE TABLE tags (
+  name VARCHAR(64) PRIMARY KEY
+) DEFAULT CHARSET=utf8mb4
+  COLLATE=utf8mb4_bin
+  COMMENT='default_tokenizer "Token\\Delimit"';
+
+SELECT mroonga_command("dump --dump_plugins no");
+
+DROP TABLE tags;
+
+--source ../../../../../include/mroonga/unload_mroonga_functions.inc
+--source ../../../../../include/mroonga/have_mroonga_deinit.inc
-- 
2.55.0

