Skip to content

Commit 27d8906

Browse files
committed
Bug# 37607195 - fprintf_string not using the actual quote parameter (mysql-5.7)
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: Idc2001a96679fe32bb48e5e3a14d724d5ab9cb9f
1 parent e7c592d commit 27d8906

File tree

3 files changed

+180
-3
lines changed

3 files changed

+180
-3
lines changed

client/mysqldump.c

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

23582358
// Put the sanitized row in the buffer.
2359-
mysql_real_escape_string_quote(mysql, pbuffer, row, row_len, '\'');
2359+
mysql_real_escape_string_quote(mysql, pbuffer, row, row_len, quote);
23602360

23612361
// Opening quote
23622362
fputc(quote, md_result_file);
@@ -4658,7 +4658,7 @@ static int dump_tablespaces(char* ts_where)
46584658
mysql_free_result(tableres);
46594659
mysql_query_with_error_report(
46604660
mysql, &tableres,
4661-
"SELECT 'TN; /*' AS TABLESPACE_NAME, 'FN' AS FILE_NAME, 'LGN' AS "
4661+
"SELECT 'T`N; /*' AS TABLESPACE_NAME, 'FN' AS FILE_NAME, 'LGN' AS "
46624662
"LOGFILE_GROUP_NAME, 77 AS EXTENT_SIZE, 88 AS INITIAL_SIZE, "
46634663
"'*/\nsystem touch foo;\n' AS ENGINE");
46644664
});

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: 107 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,111 @@ 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+
--disable_warnings
44+
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';
45+
--enable_warnings
46+
47+
CREATE TABLE "custo`mers" (
48+
"customer'_id" INT AUTO_INCREMENT PRIMARY KEY,
49+
"fir`st_`na`me" VARCHAR(50) NOT NULL,
50+
"last_'name" VARCHAR(50) NOT NULL,
51+
"em`ail" VARCHAR(100) UNIQUE NOT NULL,
52+
`pho"\ne` VARCHAR(15),
53+
"created'_'at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
54+
"updated'_'at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
55+
);
56+
57+
CREATE TABLE "prod'ucts" (
58+
"product`_`id" INT AUTO_INCREMENT PRIMARY KEY,
59+
"product'_`name" VARCHAR(100) NOT NULL,
60+
"descri`p`t`i`o`n" TEXT,
61+
"pr'i'ce" DECIMAL(10, 2) NOT NULL CHECK ("pr'i'ce" >= 0),
62+
`stock"_"qua\ntity` INT DEFAULT 0,
63+
`created'_'at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
64+
`updated"_'at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
65+
INDEX ("product'_`name")
66+
);
67+
68+
CREATE TABLE "orders" (
69+
"order_id" INT AUTO_INCREMENT PRIMARY KEY,
70+
"customer_id" INT NOT NULL,
71+
"order_date" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
72+
"status" ENUM('Pending', 'Completed', 'Cancelled') NOT NULL,
73+
"total\n" DECIMAL(10, 2) NOT NULL CHECK ("total\n" >= 0),
74+
FOREIGN KEY (customer_id) REFERENCES "custo`mers"("customer'_id") ON DELETE CASCADE,
75+
INDEX (order_date)
76+
);
77+
78+
CREATE TABLE `'order'_'items'` (
79+
`order'_'item_id` INT AUTO_INCREMENT PRIMARY KEY,
80+
`'order'_'id'` INT NOT NULL,
81+
`product'_'id` INT NOT NULL,
82+
`qua\ntity` INT NOT NULL CHECK (`qua\ntity` > 0),
83+
`p'rice` DECIMAL(10,2) NOT NULL CHECK (`p'rice` >= 0),
84+
FOREIGN KEY (`'order'_'id'`) REFERENCES "orders"(order_id) ON DELETE CASCADE,
85+
FOREIGN KEY (`product'_'id`) REFERENCES "prod'ucts"("product`_`id") ON DELETE CASCADE,
86+
UNIQUE KEY (`'order'_'id'`, `product'_'id`)
87+
);
88+
89+
--exec $MYSQL_DUMP bug37607195 --result-file=$grep_file 2>&1
90+
91+
--echo # Table 1: `'order'_'items'`
92+
--echo # `qua\ntity` must be escaped
93+
let $grep_pattern=qr| `qua\ntity` INT NOT NULL CHECK (`qua\ntity` > 0)|;
94+
--source include/grep_pattern.inc
95+
96+
--echo # Table 2: "custo`mers"
97+
--echo # "custo`mers" must be escaped
98+
let $grep_pattern=qr|CREATE TABLE `custo``mers`|;
99+
--source include/grep_pattern.inc
100+
101+
--echo # `pho"\ne` must be escaped
102+
let $grep_pattern=qr|`pho"\ne` varchar(15) DEFAULT NULL|;
103+
--source include/grep_pattern.inc
104+
105+
--echo # Table 3: "orders"
106+
--echo # `total\n` must be escaped
107+
let $grep_pattern=qr|`total\n` decimal(10,2) NOT NULL|;
108+
--source include/grep_pattern.inc
109+
110+
--echo # FOREIGN KEY (`customer_id`) REFERENCES must be escaped
111+
let $grep_pattern=qr|REFERENCES `custo``mers`|;
112+
--source include/grep_pattern.inc
113+
114+
--echo # Table 4: `prod'ucts`
115+
--echo # "descri`p`t`i`o`n" TEXT must be escaped
116+
let $grep_pattern=qr|`descri``p``t``i``o``n` text|;
117+
--source include/grep_pattern.inc
118+
119+
--echo # `stock"_"qua\ntity` must be escaped
120+
let $grep_pattern=qr|`stock"_"qua\ntity` int DEFAULT '0'|;
121+
--source include/grep_pattern.inc
122+
123+
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';
124+
125+
# Cleanup
126+
--remove_file $grep_file
127+
DROP DATABASE bug37607195;

0 commit comments

Comments
 (0)