summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2023-03-29 16:49:10 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2023-03-29 16:49:10 +0300
commita6780df49b443b172124e7e881ed0bea54d75907 (patch)
treec6d29c29bb12475ea6d775f0b44559d795fe081c
parent03b4a2d6e5b3d6e4bd88c3451cbff8ba4df7bd71 (diff)
downloadmariadb-git-a6780df49b443b172124e7e881ed0bea54d75907.tar.gz
MDEV-30453 Setting innodb_buffer_pool_filename to an empty string attempts to delete the data directory on shutdown
Let us make innodb_buffer_pool_filename a read-only variable so that a malicious user cannot cause an important file to be deleted on InnoDB shutdown. An attempt to delete a directory will fail because it is not a regular file, but what if the variable pointed to (say) ibdata1, ib_logfile0 or some *.ibd file? It does not seem to make much sense for this parameter to be configurable in the first place, but we will not change that in order to avoid breaking compatibility.
-rw-r--r--mysql-test/suite/innodb/r/innodb_buffer_pool_dump_pct.result3
-rw-r--r--mysql-test/suite/innodb/r/innodb_sys_var_valgrind.result21
-rw-r--r--mysql-test/suite/innodb/t/innodb_buffer_pool_dump_pct.test10
-rw-r--r--mysql-test/suite/innodb/t/innodb_sys_var_valgrind.test18
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_innodb.result2
-rw-r--r--storage/innobase/handler/ha_innodb.cc42
6 files changed, 6 insertions, 90 deletions
diff --git a/mysql-test/suite/innodb/r/innodb_buffer_pool_dump_pct.result b/mysql-test/suite/innodb/r/innodb_buffer_pool_dump_pct.result
index d9f5e4dfeed..fa17487df97 100644
--- a/mysql-test/suite/innodb/r/innodb_buffer_pool_dump_pct.result
+++ b/mysql-test/suite/innodb/r/innodb_buffer_pool_dump_pct.result
@@ -2,13 +2,11 @@ CREATE TABLE tab5 (col1 int auto_increment primary key,
col2 VARCHAR(25), col3 varchar(25)) ENGINE=InnoDB;
CREATE INDEX idx1 ON tab5(col2(10));
CREATE INDEX idx2 ON tab5(col3(10));
-SET GLOBAL innodb_buffer_pool_filename=ib_buffer_pool100;
SET GLOBAL innodb_buffer_pool_dump_pct=100;
SELECT variable_value INTO @IBPDS
FROM information_schema.global_status
WHERE variable_name = 'INNODB_BUFFER_POOL_DUMP_STATUS';
SET GLOBAL innodb_buffer_pool_dump_now=ON;
-SET GLOBAL innodb_buffer_pool_filename=ib_buffer_pool1;
SET GLOBAL innodb_buffer_pool_dump_pct=1;
SELECT @@global.innodb_buffer_pool_dump_pct;
@@global.innodb_buffer_pool_dump_pct
@@ -18,5 +16,4 @@ FROM information_schema.global_status
WHERE variable_name = 'INNODB_BUFFER_POOL_DUMP_STATUS';
SET GLOBAL innodb_buffer_pool_dump_now=ON;
SET GLOBAL innodb_buffer_pool_dump_pct=DEFAULT;
-SET GLOBAL innodb_buffer_pool_filename=DEFAULT;
DROP TABLE tab5;
diff --git a/mysql-test/suite/innodb/r/innodb_sys_var_valgrind.result b/mysql-test/suite/innodb/r/innodb_sys_var_valgrind.result
index 32d87b4668a..6932b8f2292 100644
--- a/mysql-test/suite/innodb/r/innodb_sys_var_valgrind.result
+++ b/mysql-test/suite/innodb/r/innodb_sys_var_valgrind.result
@@ -25,27 +25,6 @@ select @@innodb_ft_server_stopword_table;
@@innodb_ft_server_stopword_table
NULL
drop table user_stopword_1, user_stopword_2;
-select @@innodb_buffer_pool_filename;
-@@innodb_buffer_pool_filename
-ib_buffer_pool
-set @blah='hello';
-set global innodb_buffer_pool_filename = @blah;
-select @@innodb_buffer_pool_filename;
-@@innodb_buffer_pool_filename
-hello
-set global innodb_buffer_pool_filename="bye";
-select @@innodb_buffer_pool_filename;
-@@innodb_buffer_pool_filename
-bye
-set global innodb_buffer_pool_filename=NULL;
-ERROR 42000: Variable 'innodb_buffer_pool_filename' can't be set to the value of 'NULL'
-select @@innodb_buffer_pool_filename;
-@@innodb_buffer_pool_filename
-bye
-set global innodb_buffer_pool_filename=default;
-select @@innodb_buffer_pool_filename;
-@@innodb_buffer_pool_filename
-ib_buffer_pool
CREATE TABLE t1 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
opening_line TEXT(500), author VARCHAR(200), title VARCHAR(200), FULLTEXT idx
(opening_line)) ENGINE=InnoDB;
diff --git a/mysql-test/suite/innodb/t/innodb_buffer_pool_dump_pct.test b/mysql-test/suite/innodb/t/innodb_buffer_pool_dump_pct.test
index a7a414d61da..381091165ef 100644
--- a/mysql-test/suite/innodb/t/innodb_buffer_pool_dump_pct.test
+++ b/mysql-test/suite/innodb/t/innodb_buffer_pool_dump_pct.test
@@ -15,7 +15,6 @@ col2 VARCHAR(25), col3 varchar(25)) ENGINE=InnoDB;
CREATE INDEX idx1 ON tab5(col2(10));
CREATE INDEX idx2 ON tab5(col3(10));
-SET GLOBAL innodb_buffer_pool_filename=ib_buffer_pool100;
SET GLOBAL innodb_buffer_pool_dump_pct=100;
#***********************************************************
@@ -58,8 +57,7 @@ AND variable_value != @IBPDS
AND variable_value like 'Buffer pool(s) dump completed at%';
--source include/wait_condition.inc
---file_exists $MYSQLD_DATADIR/ib_buffer_pool100
-SET GLOBAL innodb_buffer_pool_filename=ib_buffer_pool1;
+--move_file $MYSQLD_DATADIR/ib_buffer_pool $MYSQLD_DATADIR/ib_buffer_pool100
SET GLOBAL innodb_buffer_pool_dump_pct=1;
SELECT @@global.innodb_buffer_pool_dump_pct;
@@ -83,17 +81,15 @@ AND variable_value != @IBPDS
AND variable_value like 'Buffer pool(s) dump completed at%';
--source include/wait_condition.inc
---file_exists $MYSQLD_DATADIR/ib_buffer_pool1
+--file_exists $MYSQLD_DATADIR/ib_buffer_pool
perl;
-my $size1 = -s "$ENV{MYSQLD_DATADIR}/ib_buffer_pool1";
+my $size1 = -s "$ENV{MYSQLD_DATADIR}/ib_buffer_pool";
my $size100 = -s "$ENV{MYSQLD_DATADIR}/ib_buffer_pool100";
die "$size100<=$size1\n" unless $size100 > $size1;
EOF
SET GLOBAL innodb_buffer_pool_dump_pct=DEFAULT;
-SET GLOBAL innodb_buffer_pool_filename=DEFAULT;
--remove_file $MYSQLD_DATADIR/ib_buffer_pool100
---remove_file $MYSQLD_DATADIR/ib_buffer_pool1
DROP TABLE tab5;
diff --git a/mysql-test/suite/innodb/t/innodb_sys_var_valgrind.test b/mysql-test/suite/innodb/t/innodb_sys_var_valgrind.test
index 2e1391355b9..4383e26877d 100644
--- a/mysql-test/suite/innodb/t/innodb_sys_var_valgrind.test
+++ b/mysql-test/suite/innodb/t/innodb_sys_var_valgrind.test
@@ -25,24 +25,6 @@ select @@innodb_ft_server_stopword_table;
drop table user_stopword_1, user_stopword_2;
-#Test innodb_buffer_pool_filename (global variable)
-
-select @@innodb_buffer_pool_filename;
-
-set @blah='hello';
-set global innodb_buffer_pool_filename = @blah;
-select @@innodb_buffer_pool_filename;
-
-set global innodb_buffer_pool_filename="bye";
-select @@innodb_buffer_pool_filename;
-
---error ER_WRONG_VALUE_FOR_VAR
-set global innodb_buffer_pool_filename=NULL;
-select @@innodb_buffer_pool_filename;
-
-set global innodb_buffer_pool_filename=default;
-select @@innodb_buffer_pool_filename;
-
#Test innodb_ft_aux_table (global variable)
CREATE TABLE t1 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
opening_line TEXT(500), author VARCHAR(200), title VARCHAR(200), FULLTEXT idx
diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
index 6a23651b9dc..7b8982dca1c 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
@@ -221,7 +221,7 @@ NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST NULL
-READ_ONLY NO
+READ_ONLY YES
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME INNODB_BUFFER_POOL_INSTANCES
SESSION_VALUE NULL
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 485e525aed8..c4a23a95d85 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -18020,44 +18020,6 @@ exit:
return;
}
-/** Validate SET GLOBAL innodb_buffer_pool_filename.
-On Windows, file names with colon (:) are not allowed.
-@param thd connection
-@param save &srv_buf_dump_filename
-@param value new value to be validated
-@return 0 for valid name */
-static int innodb_srv_buf_dump_filename_validate(THD *thd, st_mysql_sys_var*,
- void *save,
- st_mysql_value *value)
-{
- char buff[OS_FILE_MAX_PATH];
- int len= sizeof buff;
-
- if (const char *buf_name= value->val_str(value, buff, &len))
- {
-#ifdef _WIN32
- if (!is_filename_allowed(buf_name, len, FALSE))
- {
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_WRONG_ARGUMENTS,
- "InnoDB: innodb_buffer_pool_filename "
- "cannot have colon (:) in the file name.");
- return 1;
- }
-#endif /* _WIN32 */
- if (buf_name == buff)
- {
- ut_ad(static_cast<size_t>(len) < sizeof buff);
- buf_name= thd_strmake(thd, buf_name, len);
- }
-
- *static_cast<const char**>(save)= buf_name;
- return 0;
- }
-
- return 1;
-}
-
#ifdef UNIV_DEBUG
static char* srv_buffer_pool_evict;
@@ -19363,9 +19325,9 @@ static MYSQL_SYSVAR_ULONG(buffer_pool_instances, srv_buf_pool_instances,
NULL, NULL, srv_buf_pool_instances_default, 0, MAX_BUFFER_POOLS, 0);
static MYSQL_SYSVAR_STR(buffer_pool_filename, srv_buf_dump_filename,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"Filename to/from which to dump/load the InnoDB buffer pool",
- innodb_srv_buf_dump_filename_validate, NULL, SRV_BUF_DUMP_FILENAME_DEFAULT);
+ NULL, NULL, SRV_BUF_DUMP_FILENAME_DEFAULT);
static MYSQL_SYSVAR_BOOL(buffer_pool_dump_now, innodb_buffer_pool_dump_now,
PLUGIN_VAR_RQCMDARG,