mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
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.
This commit is contained in:
parent
03b4a2d6e5
commit
a6780df49b
6 changed files with 6 additions and 90 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue