mariadb: Fix CVE-2025-13699

Pick commits according to [1]

[1] https://jira.mariadb.org/browse/MDEV-37483

Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
This commit is contained in:
Vijay Anusuri 2026-03-24 14:07:41 +05:30 committed by Gyorgy Sarvari
parent 144725f1e3
commit 553e138481
3 changed files with 265 additions and 0 deletions

View File

@ -36,6 +36,8 @@ SRC_URI = "https://archive.mariadb.org/${BP}/source/${BP}.tar.gz \
file://CVE-2025-21490.patch \
file://CVE-2025-30722.patch \
file://CVE-2025-30693.patch \
file://CVE-2025-13699-1.patch \
file://CVE-2025-13699-2.patch \
"
SRC_URI:append:libc-musl = " file://ppc-remove-glibc-dep.patch"

View File

@ -0,0 +1,90 @@
From 75b000372b6d2e2dcabb280ff5f3f1e48f994ca8 Mon Sep 17 00:00:00 2001
From: Sergei Golubchik <serg@mariadb.org>
Date: Fri, 22 Aug 2025 13:21:57 +0200
Subject: [PATCH] cleanup: reusable build_path_for_table() function
Upstream-Status: Backport [https://github.com/MariaDB/server/commit/75b000372b6d2e2dcabb280ff5f3f1e48f994ca8]
CVE: CVE-2025-13699 #Dependency Patch
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
---
client/mysqldump.c | 31 ++++++++++++++++---------------
client/mysqlimport.c | 2 +-
2 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 19a2a8109e4ed..3cff3d94b67b9 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -1837,6 +1837,17 @@ static char *cover_definer_clause(const char *stmt_str,
return query_str;
}
+
+static const char* build_path_for_table(char *to, const char *dir,
+ const char *table, const char *ext)
+{
+ char tmp_path[FN_REFLEN];
+ convert_dirname(tmp_path, path, NULL);
+ my_load_path(tmp_path, tmp_path, NULL);
+ return fn_format(to, table, tmp_path, ext, MYF(MY_UNPACK_FILENAME));
+}
+
+
/*
Open a new .sql file to dump the table or view into
@@ -1851,12 +1862,9 @@ static char *cover_definer_clause(const char *stmt_str,
*/
static FILE* open_sql_file_for_table(const char* table, int flags)
{
- FILE* res;
- char filename[FN_REFLEN], tmp_path[FN_REFLEN];
- convert_dirname(tmp_path,path,NullS);
- res= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
- flags, MYF(MY_WME));
- return res;
+ char filename[FN_REFLEN];
+ return my_fopen(build_path_for_table(filename, path, table, ".sql"),
+ flags, MYF(MY_WME));
}
@@ -4043,15 +4051,9 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key,
if (path)
{
- char filename[FN_REFLEN], tmp_path[FN_REFLEN];
+ char filename[FN_REFLEN];
- /*
- Convert the path to native os format
- and resolve to the full filepath.
- */
- convert_dirname(tmp_path,path,NullS);
- my_load_path(tmp_path, tmp_path, NULL);
- fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME));
+ build_path_for_table(filename, path, table, ".txt");
/* Must delete the file that 'INTO OUTFILE' will write to */
my_delete(filename, MYF(0));
@@ -4060,7 +4062,6 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key,
to_unix_path(filename);
/* now build the query string */
-
dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ ");
dynstr_append_checked(&query_string, select_field_names.str);
dynstr_append_checked(&query_string, " INTO OUTFILE '");
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index 5682df1166850..736d8ba81e4db 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -339,7 +339,7 @@ static int write_to_table(char *filename, MYSQL *mysql)
DBUG_ENTER("write_to_table");
DBUG_PRINT("enter",("filename: %s",filename));
- fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
+ fn_format(tablename, filename, "", "", MYF(MY_REPLACE_DIR | MY_REPLACE_EXT));
if (!opt_local_file)
strmov(hard_path,filename);
else

View File

@ -0,0 +1,173 @@
From ff12ec86a5898a5a4a4eeb77be26ecbd711b3128 Mon Sep 17 00:00:00 2001
From: Sergei Golubchik <serg@mariadb.org>
Date: Sat, 23 Aug 2025 09:11:42 +0200
Subject: [PATCH] MDEV-37483 mariadb-dump -T doesn't convert table names
use my_charset_filename to build file names from table names.
this guarantees that file name will be always valid for any
table name, no matter what characters it contains and what file name
rules local filesystem has.
mariadb-import now converts back, if possible.
Upstream-Status: Backport [https://github.com/MariaDB/server/commit/ff12ec86a5898a5a4a4eeb77be26ecbd711b312]
CVE: CVE-2025-13699
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
---
client/mysqldump.c | 13 +++++++--
client/mysqlimport.c | 10 +++++++
mysql-test/main/mysqldump.result | 46 ++++++++++++++++++++++++++++++++
mysql-test/main/mysqldump.test | 42 +++++++++++++++++++++++++++++
4 files changed, 109 insertions(+), 2 deletions(-)
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 3cff3d94b67b9..7372498ffebff 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -1841,10 +1841,19 @@ static char *cover_definer_clause(const char *stmt_str,
static const char* build_path_for_table(char *to, const char *dir,
const char *table, const char *ext)
{
- char tmp_path[FN_REFLEN];
+ char filename[FN_REFLEN], tmp_path[FN_REFLEN];
convert_dirname(tmp_path, path, NULL);
my_load_path(tmp_path, tmp_path, NULL);
- return fn_format(to, table, tmp_path, ext, MYF(MY_UNPACK_FILENAME));
+ if (check_if_legal_tablename(table))
+ strxnmov(filename, sizeof(filename) - 1, table, "@@@", NULL);
+ else
+ {
+ uint errors, len;
+ len= my_convert(filename, sizeof(filename) - 1, &my_charset_filename,
+ table, (uint32)strlen(table), charset_info, &errors);
+ filename[len]= 0;
+ }
+ return fn_format(to, filename, tmp_path, ext, MYF(MY_UNPACK_FILENAME));
}
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index 736d8ba81e4db..4d826742a8dca 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -340,6 +340,16 @@ static int write_to_table(char *filename, MYSQL *mysql)
DBUG_PRINT("enter",("filename: %s",filename));
fn_format(tablename, filename, "", "", MYF(MY_REPLACE_DIR | MY_REPLACE_EXT));
+ if (strchr(tablename, '@'))
+ {
+ uint errors, len;
+ const char *csname= my_default_csname(); /* see MYSQL_SET_CHARSET_NAME */
+ CHARSET_INFO *cs= get_charset_by_csname(csname, MY_CS_PRIMARY, MYF(0));
+ len= my_convert(escaped_name, sizeof(escaped_name) - 1, cs, tablename,
+ (uint32)strlen(tablename), &my_charset_filename, &errors);
+ if (!errors)
+ strmake(tablename, escaped_name, len);
+ }
if (!opt_local_file)
strmov(hard_path,filename);
else
diff --git a/mysql-test/main/mysqldump.result b/mysql-test/main/mysqldump.result
index 7cf8a40b5c805..dd70c664d6116 100644
--- a/mysql-test/main/mysqldump.result
+++ b/mysql-test/main/mysqldump.result
@@ -6624,3 +6624,49 @@ SET character_set_client = @saved_cs_client;
drop view `v'1"2`;
drop table t1;
# End of 10.5 tests
+#
+# MDEV-37483 mariadb-dump -T doesn't convert table names
+#
+set names latin1;
+create database foo;
+use foo;
+create table `con_schöne_grüße` (a int) select 1 as a;
+create table `con` (b int) select 2 as b;
+create table `con/bar` (c int) select 3 as c;
+create table `con@home` (d int) select 4 as d;
+drop database foo;
+use test;
+con@002fbar.sql
+con@002fbar.txt
+con@@@.sql
+con@@@.txt
+con@home.sql
+con@home.txt
+con_sch@1ine_gr@1o@1je.sql
+con_sch@1ine_gr@1o@1je.txt
+show tables;
+Tables_in_test
+con
+con/bar
+con@home
+con_schöne_grüße
+test.con: Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
+test.con/bar: Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
+test.con@home: Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
+select * from `con_schöne_grüße`;
+a
+1
+select * from `con`;
+b
+2
+select * from `con/bar`;
+c
+3
+select * from `con@home`;
+d
+4
+drop table `con_schöne_grüße`;
+drop table `con`;
+drop table `con/bar`;
+drop table `con@home`;
+# End of 10.6 tests
diff --git a/mysql-test/main/mysqldump.test b/mysql-test/main/mysqldump.test
index 6ffe3a8af419b..971e7f29fa806 100644
--- a/mysql-test/main/mysqldump.test
+++ b/mysql-test/main/mysqldump.test
@@ -3035,3 +3035,45 @@ drop view `v'1"2`; # "'
drop table t1;
--echo # End of 10.5 tests
+
+--echo #
+--echo # MDEV-37483 mariadb-dump -T doesn't convert table names
+--echo #
+set names latin1;
+create database foo;
+use foo;
+
+create table `con_schöne_grüße` (a int) select 1 as a;
+create table `con` (b int) select 2 as b;
+create table `con/bar` (c int) select 3 as c;
+create table `con@home` (d int) select 4 as d;
+exec $MYSQL_DUMP foo --tab $MYSQLTEST_VARDIR/tmp;
+drop database foo;
+use test;
+move_file $MYSQLTEST_VARDIR/tmp/con@0040home.sql $MYSQLTEST_VARDIR/tmp/con@home.sql;
+move_file $MYSQLTEST_VARDIR/tmp/con@0040home.txt $MYSQLTEST_VARDIR/tmp/con@home.txt;
+list_files $MYSQLTEST_VARDIR/tmp con*;
+exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/con@@@.sql;
+exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/con@002fbar.sql;
+exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/con_sch@1ine_gr@1o@1je.sql;
+exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/con@home.sql;
+show tables;
+exec $MYSQL_IMPORT test $MYSQLTEST_VARDIR/tmp/con@@@.txt;
+exec $MYSQL_IMPORT test $MYSQLTEST_VARDIR/tmp/con@002fbar.txt;
+if (`select @@version like '10.6.%'`) {
+# utf8 console output on Windows is fixed in MDEV-26713, until then
+--disable_result_log
+}
+exec $MYSQL_IMPORT test $MYSQLTEST_VARDIR/tmp/con_sch@1ine_gr@1o@1je.txt;
+--enable_result_log
+exec $MYSQL_IMPORT test $MYSQLTEST_VARDIR/tmp/con@home.txt;
+select * from `con_schöne_grüße`;
+select * from `con`;
+select * from `con/bar`;
+select * from `con@home`;
+drop table `con_schöne_grüße`;
+drop table `con`;
+drop table `con/bar`;
+drop table `con@home`;
+
+--echo # End of 10.6 tests