Skip to content

Commit 8afeb98

Browse files
committed
Bug# 37607195 - fprintf_string not using the actual quote parameter (mysql-trunk)
The fprintf_string function present in mysqldump takes the quote of the string as a parameter, but does not pass it to the mysql_real_escape_string_quote to escape the string. The fix is to pass the string quote to mysql_real_escape_string_quote as a parameter. Added a test case. Change-Id: I462c5cf46341f9326a18324e85892600a7c08395
1 parent f239a3a commit 8afeb98

File tree

3 files changed

+178
-3
lines changed

3 files changed

+178
-3
lines changed

client/mysqldump.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2296,7 +2296,7 @@ static void fprintf_string(char *row, ulong row_len, char quote,
22962296
pbuffer = (char *)my_malloc(PSI_NOT_INSTRUMENTED, curr_row_size, MYF(0));
22972297

22982298
// Put the sanitized row in the buffer.
2299-
mysql_real_escape_string_quote(mysql, pbuffer, row, row_len, '\'');
2299+
mysql_real_escape_string_quote(mysql, pbuffer, row, row_len, quote);
23002300

23012301
// Opening quote
23022302
fputc(quote, md_result_file);
@@ -4470,7 +4470,7 @@ static int dump_tablespaces(char *ts_where) {
44704470
mysql_free_result(tableres);
44714471
mysql_query_with_error_report(
44724472
mysql, &tableres,
4473-
"SELECT 'TN; /*' AS TABLESPACE_NAME, 'FN' AS FILE_NAME, 'LGN' AS "
4473+
"SELECT 'T`N; /*' AS TABLESPACE_NAME, 'FN' AS FILE_NAME, 'LGN' AS "
44744474
"LOGFILE_GROUP_NAME, 77 AS EXTENT_SIZE, 88 AS INITIAL_SIZE, "
44754475
"'*/\nsystem touch foo;\n' AS ENGINE");
44764476
});

mysql-test/r/mysqldump-tablespace-escape.result

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,78 @@
22
# Bug#36816986 - MySQL Shell command injection
33
#
44
CREATE DATABASE bug36816986;
5+
USE bug36816986;
56
-- Run mysqldump with tablespace_injection_test.
67
The test injected string must be found:
78
Pattern found.
9+
The ` must be escaped:
10+
Pattern found.
811
DROP DATABASE bug36816986;
12+
13+
#######################################
14+
15+
#
16+
# Bug#37607195 - fprintf_string not using the actual quote parameter
17+
#
18+
CREATE DATABASE bug37607195;
19+
USE bug37607195;
20+
Create a bunch of tables with numerous ` ' " \n etc.
21+
SET @@sql_mode='ANSI_QUOTES,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
22+
CREATE TABLE "custo`mers" (
23+
"customer'_id" INT AUTO_INCREMENT PRIMARY KEY,
24+
"fir`st_`na`me" VARCHAR(50) NOT NULL,
25+
"last_'name" VARCHAR(50) NOT NULL,
26+
"em`ail" VARCHAR(100) UNIQUE NOT NULL,
27+
`pho"\ne` VARCHAR(15),
28+
"created'_'at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
29+
"updated'_'at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
30+
);
31+
CREATE TABLE "prod'ucts" (
32+
"product`_`id" INT AUTO_INCREMENT PRIMARY KEY,
33+
"product'_`name" VARCHAR(100) NOT NULL,
34+
"descri`p`t`i`o`n" TEXT,
35+
"pr'i'ce" DECIMAL(10, 2) NOT NULL CHECK ("pr'i'ce" >= 0),
36+
`stock"_"qua\ntity` INT DEFAULT 0,
37+
`created'_'at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
38+
`updated"_'at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
39+
INDEX ("product'_`name")
40+
);
41+
CREATE TABLE "orders" (
42+
"order_id" INT AUTO_INCREMENT PRIMARY KEY,
43+
"customer_id" INT NOT NULL,
44+
"order_date" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
45+
"status" ENUM('Pending', 'Completed', 'Cancelled') NOT NULL,
46+
"total\n" DECIMAL(10, 2) NOT NULL CHECK ("total\n" >= 0),
47+
FOREIGN KEY (customer_id) REFERENCES "custo`mers"("customer'_id") ON DELETE CASCADE,
48+
INDEX (order_date)
49+
);
50+
CREATE TABLE `'order'_'items'` (
51+
`order'_'item_id` INT AUTO_INCREMENT PRIMARY KEY,
52+
`'order'_'id'` INT NOT NULL,
53+
`product'_'id` INT NOT NULL,
54+
`qua\ntity` INT NOT NULL CHECK (`qua\ntity` > 0),
55+
`p'rice` DECIMAL(10,2) NOT NULL CHECK (`p'rice` >= 0),
56+
FOREIGN KEY (`'order'_'id'`) REFERENCES "orders"(order_id) ON DELETE CASCADE,
57+
FOREIGN KEY (`product'_'id`) REFERENCES "prod'ucts"("product`_`id") ON DELETE CASCADE,
58+
UNIQUE KEY (`'order'_'id'`, `product'_'id`)
59+
);
60+
# Table 1: `'order'_'items'`
61+
# `qua\ntity` must be escaped
62+
Pattern found.
63+
# Table 2: "custo`mers"
64+
# "custo`mers" must be escaped
65+
Pattern found.
66+
# `pho"\ne` must be escaped
67+
Pattern found.
68+
# Table 3: "orders"
69+
# `total\n` must be escaped
70+
Pattern found.
71+
# FOREIGN KEY (`customer_id`) REFERENCES must be escaped
72+
Pattern found.
73+
# Table 4: `prod'ucts`
74+
# "descri`p`t`i`o`n" TEXT must be escaped
75+
Pattern found.
76+
# `stock"_"qua\ntity` must be escaped
77+
Pattern found.
78+
SET @@sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
79+
DROP DATABASE bug37607195;

mysql-test/t/mysqldump-tablespace-escape.test

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ let $grep_file= $MYSQLTEST_VARDIR/tmp/bug36816986.sql;
88
let $grep_output=boolean;
99

1010
CREATE DATABASE bug36816986;
11+
USE bug36816986;
1112

1213
--echo -- Run mysqldump with tablespace_injection_test.
1314
--exec $MYSQL_DUMP --debug="d,tablespace_injection_test" --result-file=$grep_file bug36816986 --all-tablespaces 2>&1
@@ -16,6 +17,109 @@ CREATE DATABASE bug36816986;
1617
let $grep_pattern=qr| ENGINE=\*/\nsystem touch foo|;
1718
--source include/grep_pattern.inc
1819

19-
# Cleanup
20+
--echo The ` must be escaped:
21+
let $grep_pattern=qr|CREATE TABLESPACE `T``N; /*`|;
22+
--source include/grep_pattern.inc
23+
2024
--remove_file $grep_file
2125
DROP DATABASE bug36816986;
26+
27+
--echo
28+
--echo #######################################
29+
--echo
30+
31+
--echo #
32+
--echo # Bug#37607195 - fprintf_string not using the actual quote parameter
33+
--echo #
34+
35+
CREATE DATABASE bug37607195;
36+
USE bug37607195;
37+
38+
let $grep_file= $MYSQLTEST_VARDIR/tmp/bug37607195.sql;
39+
let $grep_output=boolean;
40+
41+
--echo Create a bunch of tables with numerous ` ' " \n etc.
42+
43+
SET @@sql_mode='ANSI_QUOTES,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
44+
45+
CREATE TABLE "custo`mers" (
46+
"customer'_id" INT AUTO_INCREMENT PRIMARY KEY,
47+
"fir`st_`na`me" VARCHAR(50) NOT NULL,
48+
"last_'name" VARCHAR(50) NOT NULL,
49+
"em`ail" VARCHAR(100) UNIQUE NOT NULL,
50+
`pho"\ne` VARCHAR(15),
51+
"created'_'at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
52+
"updated'_'at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
53+
);
54+
55+
CREATE TABLE "prod'ucts" (
56+
"product`_`id" INT AUTO_INCREMENT PRIMARY KEY,
57+
"product'_`name" VARCHAR(100) NOT NULL,
58+
"descri`p`t`i`o`n" TEXT,
59+
"pr'i'ce" DECIMAL(10, 2) NOT NULL CHECK ("pr'i'ce" >= 0),
60+
`stock"_"qua\ntity` INT DEFAULT 0,
61+
`created'_'at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
62+
`updated"_'at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
63+
INDEX ("product'_`name")
64+
);
65+
66+
CREATE TABLE "orders" (
67+
"order_id" INT AUTO_INCREMENT PRIMARY KEY,
68+
"customer_id" INT NOT NULL,
69+
"order_date" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
70+
"status" ENUM('Pending', 'Completed', 'Cancelled') NOT NULL,
71+
"total\n" DECIMAL(10, 2) NOT NULL CHECK ("total\n" >= 0),
72+
FOREIGN KEY (customer_id) REFERENCES "custo`mers"("customer'_id") ON DELETE CASCADE,
73+
INDEX (order_date)
74+
);
75+
76+
CREATE TABLE `'order'_'items'` (
77+
`order'_'item_id` INT AUTO_INCREMENT PRIMARY KEY,
78+
`'order'_'id'` INT NOT NULL,
79+
`product'_'id` INT NOT NULL,
80+
`qua\ntity` INT NOT NULL CHECK (`qua\ntity` > 0),
81+
`p'rice` DECIMAL(10,2) NOT NULL CHECK (`p'rice` >= 0),
82+
FOREIGN KEY (`'order'_'id'`) REFERENCES "orders"(order_id) ON DELETE CASCADE,
83+
FOREIGN KEY (`product'_'id`) REFERENCES "prod'ucts"("product`_`id") ON DELETE CASCADE,
84+
UNIQUE KEY (`'order'_'id'`, `product'_'id`)
85+
);
86+
87+
--exec $MYSQL_DUMP bug37607195 --init-command="SET @@sql_mode='ANSI_QUOTES,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'" --result-file=$grep_file 2>&1
88+
89+
--echo # Table 1: `'order'_'items'`
90+
--echo # `qua\ntity` must be escaped
91+
let $grep_pattern=qr| `qua\ntity` INT NOT NULL CHECK (`qua\ntity` > 0)|;
92+
--source include/grep_pattern.inc
93+
94+
--echo # Table 2: "custo`mers"
95+
--echo # "custo`mers" must be escaped
96+
let $grep_pattern=qr|CREATE TABLE `custo``mers`|;
97+
--source include/grep_pattern.inc
98+
99+
--echo # `pho"\ne` must be escaped
100+
let $grep_pattern=qr|`pho"\ne` varchar(15) DEFAULT NULL|;
101+
--source include/grep_pattern.inc
102+
103+
--echo # Table 3: "orders"
104+
--echo # `total\n` must be escaped
105+
let $grep_pattern=qr|`total\n` decimal(10,2) NOT NULL|;
106+
--source include/grep_pattern.inc
107+
108+
--echo # FOREIGN KEY (`customer_id`) REFERENCES must be escaped
109+
let $grep_pattern=qr|REFERENCES `custo``mers`|;
110+
--source include/grep_pattern.inc
111+
112+
--echo # Table 4: `prod'ucts`
113+
--echo # "descri`p`t`i`o`n" TEXT must be escaped
114+
let $grep_pattern=qr|`descri``p``t``i``o``n` text|;
115+
--source include/grep_pattern.inc
116+
117+
--echo # `stock"_"qua\ntity` must be escaped
118+
let $grep_pattern=qr|`stock"_"qua\ntity` int DEFAULT '0'|;
119+
--source include/grep_pattern.inc
120+
121+
SET @@sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
122+
123+
# Cleanup
124+
--remove_file $grep_file
125+
DROP DATABASE bug37607195;

0 commit comments

Comments
 (0)