#At file:///localhome/jl208045/mysql/mysql-6.0-backup-34171/
2683 Jorgen Loland 2008-08-27
Bug#34171 - "Backup: ignoring --secure-file-priv"
Before patch: Backup code ignored secure-file-priv option,
allowing backup to write to any location
After patch: Backup and restore are not allowed to write or read
outside path in secure-file-priv option if option has been
specified.
added:
mysql-test/r/backup_securefilepriv.result
mysql-test/t/backup_securefilepriv-master.opt
mysql-test/t/backup_securefilepriv.test
modified:
mysql-test/lib/mtr_report.pl
mysql-test/r/backup_backupdir.result
mysql-test/t/backup_backupdir.test
sql/backup/backup_kernel.h
sql/backup/kernel.cc
sql/backup/stream.cc
sql/backup/stream.h
per-file comments:
mysql-test/lib/mtr_report.pl
Added expected error for backup_securefilepriv
mysql-test/r/backup_backupdir.result
Result modified to handle modified test file due to secure-file-priv
mysql-test/r/backup_securefilepriv.result
New result file for secure-file-priv backup tests
mysql-test/t/backup_backupdir.test
Tests modified to handle secure-file-priv
mysql-test/t/backup_securefilepriv-master.opt
Sets secure-file-priv option for backup_securefilepriv test
mysql-test/t/backup_securefilepriv.test
New test file for secure-file-priv backup tests
sql/backup/backup_kernel.h
Added private function report_stream_open_failure
sql/backup/kernel.cc
Improved error handling for errors reported by *Stream::open
sql/backup/stream.cc
Adds check for secure-file-priv option when opening backup/restore streams. Also some documentation bug fixes for Stream::prepare_path
sql/backup/stream.h
Added private method test_secure_file_priv_access, *Stream::open() now returns int
=== modified file 'mysql-test/lib/mtr_report.pl'
--- a/mysql-test/lib/mtr_report.pl 2008-08-20 13:23:10 +0000
+++ b/mysql-test/lib/mtr_report.pl 2008-08-27 09:26:33 +0000
@@ -357,6 +357,12 @@ sub mtr_report_stats ($) {
(
/Restore: Tablespace .* needed by tables being restored has changed on the server/
) or
+
+ # The backup_securefilepriv test triggers error below on purpose
+ ($testname eq 'main.backup_securefilepriv') and
+ (
+ /Backup: The MySQL server is running with the /
+ ) or
# The views test triggers errors below on purpose
($testname eq 'main.backup_views') and
=== modified file 'mysql-test/r/backup_backupdir.result'
--- a/mysql-test/r/backup_backupdir.result 2008-08-08 17:21:31 +0000
+++ b/mysql-test/r/backup_backupdir.result 2008-08-27 09:26:33 +0000
@@ -41,11 +41,16 @@ backup_id
#
Ensure backup image file went to the correct location
Try a backup to an invalid relative path.
-BACKUP DATABASE bup_backupdir TO '../../../../../../../../../../../../../../../../../../bup_backupdir5.bak';
-ERROR HY000: Can't write to backup location '../../../../../../../../../../../../../../../../../../bup_backup' (file already exists?)
+BACKUP DATABASE bup_backupdir TO '../not/there/bup_backupdir5.bak';
+ERROR HY000: Can't write to backup location '../not/there/bup_backupdir5.bak' (file already exists?)
+
Try a backup to an invalid hard path.
-BACKUP DATABASE bup_backupdir TO '/dev/not/there/either/bup_backupdir6.bak';
-ERROR HY000: Can't write to backup location '/dev/not/there/either/bup_backupdir6.bak' (file already exists?)
+*Actual BACKUP DATABASE command not printed due to non-deterministic path.
+*Performing:
+*BACKUP DATABASE bup_backupdir TO '$MYSQLTEST_VARDIR/master_data/not/there/either/bup_backupdir6.bak';
+ERROR HY000: Can't write to backup location '$MYSQLTEST_VARDIR/master_data/not/there/either/bup_backupdir6.bak' (file already exists?)
+
+Attempt to set the backupdir to something invalid.
SET @@global.backupdir = 'This_is_really_stupid/not/there/at/all';
Warnings:
Warning 1725 The path specified for the system variable backupdir cannot be accessed or is invalid. ref: This_is_really_stupid/not/there/at/all
=== added file 'mysql-test/r/backup_securefilepriv.result'
--- a/mysql-test/r/backup_securefilepriv.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/backup_securefilepriv.result 2008-08-27 09:26:33 +0000
@@ -0,0 +1,60 @@
+Initializing tests
+Create directories for backup images
+Creating database and populating tables
+DROP DATABASE IF EXISTS mysqltest;
+CREATE DATABASE mysqltest;
+CREATE TABLE mysqltest.t1 (i int);
+INSERT INTO mysqltest.t1 VALUES (1),(2),(3),(4),(5),(10),(15),(100);
+
+Starting tests
+
+Backup to path specified by --secure-file-priv option
+(MYSQLTEST_VARDIR/master-data/securefilepriv_path)
+BACKUP DATABASE mysqltest TO 'securefilepriv_path/bup_sfp1.bak';
+backup_id
+#
+Ensure backup image file went to the correct location
+
+Backup to subpath of path specified by --secure-file-priv option
+(MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath)
+BACKUP DATABASE mysqltest TO 'securefilepriv_path/subpath/bup_sfp2.bak';
+backup_id
+#
+Ensure backup image file went to the correct location
+
+Change backupdir to securefilepriv_path/subpath
+(MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath)
+SET @@global.backupdir = 'securefilepriv_path/subpath';
+
+Backup to subpath of path specified by --secure-file-priv option,
+no dir in backup file name
+(MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath)
+BACKUP DATABASE mysqltest TO 'bup_sfp3.bak';
+backup_id
+#
+Ensure backup image file went to the correct location
+
+Backup to path specified by --secure-file-priv,
+relative path in backup file name
+(MYSQLTEST_VARDIR/master-data/securefilepriv_path)
+BACKUP DATABASE mysqltest TO '../bup_sfp4.bak';
+backup_id
+#
+Ensure backup image file went to the correct location
+
+Backup to relative path outside path specified by --secure-file-priv
+option should fail
+BACKUP DATABASE mysqltest TO '../../bup_sfp_fail1.bak';
+ERROR HY000: The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
+
+Reset backupdir to MYSQLTEST_VARDIR/master-data/
+SET @@global.backupdir = @@global.datadir;
+
+Backup to other path than specified by --secure-file-priv should fail
+BACKUP DATABASE mysqltest TO 'bup_sfp_fail2.bak';
+ERROR HY000: The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
+
+Cleanup
+
+DROP TABLE mysqltest.t1;
+DROP DATABASE mysqltest;
=== modified file 'mysql-test/t/backup_backupdir.test'
--- a/mysql-test/t/backup_backupdir.test 2008-08-08 17:21:31 +0000
+++ b/mysql-test/t/backup_backupdir.test 2008-08-27 09:26:33 +0000
@@ -75,15 +75,24 @@ BACKUP DATABASE bup_backupdir TO '../../
--echo Try a backup to an invalid relative path.
--error ER_BACKUP_WRITE_LOC
-BACKUP DATABASE bup_backupdir TO '../../../../../../../../../../../../../../../../../../bup_backupdir5.bak';
+BACKUP DATABASE bup_backupdir TO '../not/there/bup_backupdir5.bak';
+--echo
--echo Try a backup to an invalid hard path.
+
+--echo *Actual BACKUP DATABASE command not printed due to non-deterministic path.
+--echo *Performing:
+--echo *BACKUP DATABASE bup_backupdir TO '\$MYSQLTEST_VARDIR/master_data/not/there/either/bup_backupdir6.bak';
+# Do not print the SQL command to result file because dir is not deterministic across hosts
+--disable_query_log
+# Replace actual dir in error message because $MYSQLTEST_VARDIR is not deterministic
+replace_regex /(location ').*'/location '$MYSQLTEST_VARDIR\/master_data\/not\/there\/either\/bup_backupdir6.bak'/ ;
--error ER_BACKUP_WRITE_LOC
-BACKUP DATABASE bup_backupdir TO '/dev/not/there/either/bup_backupdir6.bak';
+--eval BACKUP DATABASE bup_backupdir TO '$MYSQLTEST_VARDIR/master_data/not/there/either/bup_backupdir6.bak';
+--enable_query_log
-#
-# Attempt to set the backupdir to something invalid.
-#
+--echo
+--echo Attempt to set the backupdir to something invalid.
SET @@global.backupdir = 'This_is_really_stupid/not/there/at/all';
--echo Cleanup
=== added file 'mysql-test/t/backup_securefilepriv-master.opt'
--- a/mysql-test/t/backup_securefilepriv-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/backup_securefilepriv-master.opt 2008-08-27 09:26:33 +0000
@@ -0,0 +1 @@
+--secure-file-priv=$MYSQLTEST_VARDIR/master-data/securefilepriv_path
=== added file 'mysql-test/t/backup_securefilepriv.test'
--- a/mysql-test/t/backup_securefilepriv.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/backup_securefilepriv.test 2008-08-27 09:26:33 +0000
@@ -0,0 +1,118 @@
+#
+# Purpose: Backup images should only be allowed to be written to the
+# path specified by --secure-file-priv option or a sub-path of it.
+#
+# See backup_securefilepriv-master.opt for --secure-file-priv command line option
+#
+# backupdir is MYSQLTEST_VARDIR/master-data/
+# secure-file-priv is MYSQLTEST_VARDIR/master-data/securefilepriv_path/
+
+--echo Initializing tests
+
+--error 0,1
+rmdir $MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath;
+--error 0,1
+rmdir $MYSQLTEST_VARDIR/master-data/securefilepriv_path;
+
+--echo Create directories for backup images
+mkdir $MYSQLTEST_VARDIR/master-data/securefilepriv_path;
+mkdir $MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath;
+
+--echo Creating database and populating tables
+
+--disable_warnings
+DROP DATABASE IF EXISTS mysqltest;
+--enable_warnings
+
+CREATE DATABASE mysqltest;
+
+CREATE TABLE mysqltest.t1 (i int);
+
+INSERT INTO mysqltest.t1 VALUES (1),(2),(3),(4),(5),(10),(15),(100);
+
+--echo
+--echo Starting tests
+
+--echo
+--echo Backup to path specified by --secure-file-priv option
+--echo (MYSQLTEST_VARDIR/master-data/securefilepriv_path)
+--replace_column 1 #
+BACKUP DATABASE mysqltest TO 'securefilepriv_path/bup_sfp1.bak';
+
+--echo Ensure backup image file went to the correct location
+--file_exists $MYSQLTEST_VARDIR/master-data/securefilepriv_path/bup_sfp1.bak
+
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/securefilepriv_path/bup_sfp1.bak
+
+--echo
+--echo Backup to subpath of path specified by --secure-file-priv option
+--echo (MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath)
+--replace_column 1 #
+BACKUP DATABASE mysqltest TO 'securefilepriv_path/subpath/bup_sfp2.bak';
+
+--echo Ensure backup image file went to the correct location
+--file_exists $MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath/bup_sfp2.bak
+
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath/bup_sfp2.bak
+
+--echo
+--echo Change backupdir to securefilepriv_path/subpath
+--echo (MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath)
+SET @@global.backupdir = 'securefilepriv_path/subpath';
+
+--echo
+--echo Backup to subpath of path specified by --secure-file-priv option,
+--echo no dir in backup file name
+--echo (MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath)
+--replace_column 1 #
+BACKUP DATABASE mysqltest TO 'bup_sfp3.bak';
+
+--echo Ensure backup image file went to the correct location
+--file_exists $MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath/bup_sfp3.bak
+
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath/bup_sfp3.bak
+
+--echo
+--echo Backup to path specified by --secure-file-priv,
+--echo relative path in backup file name
+--echo (MYSQLTEST_VARDIR/master-data/securefilepriv_path)
+--replace_column 1 #
+BACKUP DATABASE mysqltest TO '../bup_sfp4.bak';
+
+--echo Ensure backup image file went to the correct location
+--file_exists $MYSQLTEST_VARDIR/master-data/securefilepriv_path/bup_sfp4.bak
+
+--error 0,1
+--remove_file $MYSQLTEST_VARDIR/master-data/securefilepriv_path/bup_sfp4.bak
+
+# Tests that fail
+
+--echo
+--echo Backup to relative path outside path specified by --secure-file-priv
+--echo option should fail
+--error ER_OPTION_PREVENTS_STATEMENT
+BACKUP DATABASE mysqltest TO '../../bup_sfp_fail1.bak';
+
+--echo
+--echo Reset backupdir to MYSQLTEST_VARDIR/master-data/
+SET @@global.backupdir = @@global.datadir;
+
+--echo
+--echo Backup to other path than specified by --secure-file-priv should fail
+--error ER_OPTION_PREVENTS_STATEMENT
+BACKUP DATABASE mysqltest TO 'bup_sfp_fail2.bak';
+
+--echo
+--echo Cleanup
+--echo
+
+DROP TABLE mysqltest.t1;
+DROP DATABASE mysqltest;
+
+--error 0,1,2
+rmdir $MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath;
+--error 0,1,2
+rmdir $MYSQLTEST_VARDIR/master-data/securefilepriv_path;
=== modified file 'sql/backup/backup_kernel.h'
--- a/sql/backup/backup_kernel.h 2008-08-08 17:21:31 +0000
+++ b/sql/backup/backup_kernel.h 2008-08-27 09:26:33 +0000
@@ -129,6 +129,8 @@ class Backup_restore_ctx: public backup:
int lock_tables_for_restore();
int unlock_tables();
+ int report_stream_open_failure(int open_error, LEX_STRING location);
+
friend class Backup_info;
friend class Restore_info;
friend int backup_init();
=== modified file 'sql/backup/kernel.cc'
--- a/sql/backup/kernel.cc 2008-08-21 11:36:09 +0000
+++ b/sql/backup/kernel.cc 2008-08-27 09:26:33 +0000
@@ -551,13 +551,10 @@ Backup_restore_ctx::prepare_for_backup(S
return NULL;
}
- if (!s->open())
+ int my_open_status= s->open();
+ if (my_open_status != 0)
{
- /*
- For this error, use the actual value returned instead of the
- path complimented with backupdir.
- */
- fatal_error(ER_BACKUP_WRITE_LOC, orig_loc.str);
+ report_stream_open_failure(my_open_status, orig_loc);
return NULL;
}
@@ -634,13 +631,10 @@ Backup_restore_ctx::prepare_for_restore(
return NULL;
}
- if (!s->open())
+ int my_open_status= s->open();
+ if (my_open_status != 0)
{
- /*
- For this error, use the actual value returned instead of the
- path complimented with backupdir.
- */
- fatal_error(ER_BACKUP_READ_LOC, orig_loc.str);
+ report_stream_open_failure(my_open_status, orig_loc);
return NULL;
}
@@ -1130,6 +1124,40 @@ int Backup_restore_ctx::do_restore()
DBUG_RETURN(0);
}
+/**
+ Report stream open error by calling fatal_error, effectively moving
+ context object into error state.
+
+ @return error code given as input or the one stored in the context
+ object if a fatal error has already been reported.
+ */
+int Backup_restore_ctx::report_stream_open_failure(int my_open_status,
+ LEX_STRING location)
+{
+ int error= 0;
+ switch (my_open_status) {
+ case ER_OPTION_PREVENTS_STATEMENT:
+ error= fatal_error(ER_OPTION_PREVENTS_STATEMENT, "--secure-file-priv");
+ break;
+ case ER_BACKUP_WRITE_LOC:
+ /*
+ For this error, use the actual value returned instead of the
+ path complimented with backupdir.
+ */
+ error= fatal_error(ER_BACKUP_WRITE_LOC, location.str);
+ break;
+ case ER_BACKUP_READ_LOC:
+ /*
+ For this error, use the actual value returned instead of the
+ path complimented with backupdir.
+ */
+ error= fatal_error(ER_BACKUP_READ_LOC, location.str);
+ break;
+ default:
+ DBUG_ASSERT(FALSE);
+ }
+ return error;
+}
namespace backup {
=== modified file 'sql/backup/stream.cc'
--- a/sql/backup/stream.cc 2008-08-08 17:21:31 +0000
+++ b/sql/backup/stream.cc 2008-08-27 09:26:33 +0000
@@ -218,6 +218,9 @@ Stream::Stream(Logger &log, ::String *ba
For example, if backupdir = '/dev/tmp' and orig_log = '../backup.bak', the
combined path is = '/dev/backup.bak'.
+ Note: fn_format may likely be used instead of this function - will
+ not be changed unless bugs are found.
+
@returns
0 if success
1 if cannot be combined. Note: m_path is set to '' when this occurs to
@@ -289,6 +292,31 @@ int Stream::prepare_path(::String *backu
int path_len= 0;
/*
+ The full path is needed to test for secure-file-priv option in
+ Stream::open. If not full, replace backupdir with the full
+ path name, which is relative to datadir (i.e., global variable
+ mysql_real_data_home)
+ */
+ if (!test_if_hard_path(backupdir->c_ptr()))
+ {
+ char full_path[FN_LEN];
+
+ /*
+ MY_UNPACK_FILENAME "~/" will be changed to full path
+ MY_RELATIVE_PATH path is constructed from the base path
+ mysql_real_data_home combined with the
+ relative path backupdir. Also handles
+ "../" in backupdir and converts dirname
+ to fit this system
+ */
+ fn_format(full_path, backupdir->c_ptr(), mysql_real_data_home, "",
+ MY_UNPACK_FILENAME | MY_RELATIVE_PATH);
+
+ uint32 full_path_len= strlen(full_path);
+ (*backupdir).copy(full_path, full_path_len, &::my_charset_bin);
+ }
+
+ /*
Prepare the path using the backupdir iff no relative path
or no hard path included.
@@ -301,9 +329,9 @@ int Stream::prepare_path(::String *backu
Make relative to backupdir.
Example BACKUP DATATBASE ... TO '../monthly/dec.bak'
- If backupdir = '/dev/daily/backup' then the
+ If backupdir = '/dev/daily' then the
calculated path becomes
- '/dev/monthly/backup/dec.bak'
+ '/dev/monthly/dec.bak'
*/
char new_path[FN_LEN];
if (make_relative_path(new_path, orig_loc.str, backupdir))
@@ -316,42 +344,85 @@ int Stream::prepare_path(::String *backu
else if (!test_if_hard_path(orig_loc.str))
{
/*
- Case 2: Backup image file name has hard path.
+ Case 2: Backup image file name has no path or has a subpath.
- Example BACKUP DATATBASE ... TO '/dev/dec.bak'
- If backupdir = '/dev/daily/backup' then the
+ Example BACKUP DATABASE ... TO 'week2.bak'
+ If backupdir = '/dev/weekly/' then the
calculated path becomes
- '/dev/dec.bak'
+ '/dev/weekly/week2.bak'
+ Example BACKUP DATABASE ... TO 'jan/day1.bak'
+ If backupdir = '/dev/monthly/' then the
+ calculated path becomes
+ '/dev/monthly/jan/day1.bak'
*/
path_len=backupdir->length() + orig_loc.length + 1;
m_path.alloc(path_len);
fn_format(m_path.c_ptr(), orig_loc.str, backupdir->c_ptr(), "",
- MY_UNPACK_FILENAME);
+ MY_UNPACK_FILENAME | MY_RELATIVE_PATH);
}
else
{
/*
- Case 3: Backup image file name has no path.
+ Case 3: Backup image file name has hard path.
- Example BACKUP DATATBASE ... TO 'week2.bak'
- If backupdir = '/dev/weekly/backup' then the
+ Example BACKUP DATATBASE ... TO '/dev/dec.bak'
+ If backupdir = '/dev/daily/backup' then the
calculated path becomes
- '/dev/weekly/week2.bak'
+ '/dev/dec.bak'
*/
path_len= orig_loc.length + 1;
m_path.alloc(path_len);
m_path.length(0);
m_path.append(orig_loc.str);
+ // Convert directory name to fit this system
+ convert_dirname(m_path.c_ptr(), orig_loc.str, NullS);
}
m_path.length(path_len);
return 0;
}
-bool Stream::open()
+/**
+ Check if secure-file-priv option has been set and if so, whether
+ or not backup tries to write to the path (or a sub-path) specified
+ by secure-file-priv.
+
+ Reports error ER_OPTION_PREVENTS_STATEMENT if backup tries to write
+ to a different path than specified by secure-file-priv.
+
+ @retval TRUE backup is allowed to write to this path
+ @retval FALSE backup is not allowed to write to this path. Side
+ effect: error is reported
+*/
+bool Stream::test_secure_file_priv_access(char *path) {
+ bool has_access = !opt_secure_file_priv || // option not specified, or
+ !strncmp(opt_secure_file_priv, path, // path is (subpath of)
+ strlen(opt_secure_file_priv)); // secure-file-priv option
+ if (!has_access)
+ m_log.report_error(ER_OPTION_PREVENTS_STATEMENT, "--secure-file-priv");
+
+ return has_access;
+}
+
+/**
+ Open a stream.
+
+ @retval 0 if stream was successfully opened
+ @retval ER_OPTION_PREVENTS_STATEMENT if secure-file-priv option
+ prevented stream open from this path
+ @retval -1 if open failed for another reason
+ */
+int Stream::open()
{
close();
+ if (!test_secure_file_priv_access(m_path.c_ptr()))
+ return ER_OPTION_PREVENTS_STATEMENT;
+
m_fd= my_open(m_path.c_ptr(), m_flags, MYF(0));
- return m_fd >= 0;
+
+ if (!(m_fd >= 0))
+ return -1;
+
+ return 0;
}
void Stream::close()
@@ -445,12 +516,14 @@ bool Output_stream::init()
/**
Open and initialize backup stream for writing.
- @retval TRUE operation succeeded
- @retval FALSE operation failed
+ @retval 0 operation succeeded
+ @retval ER_OPTION_PREVENTS_STATEMENT secure-file-priv option
+ prevented stream open from this path
+ @retval ER_BACKUP_WRITE_LOC open failed for another reason
@todo Report errors.
*/
-bool Output_stream::open()
+int Output_stream::open()
{
MY_STAT stat_info;
close();
@@ -462,10 +535,10 @@ bool Output_stream::open()
else
m_flags= O_WRONLY|O_CREAT|O_EXCL|O_TRUNC;
- bool ret= Stream::open();
+ int ret= Stream::open();
- if (!ret)
- return FALSE;
+ if (ret != 0)
+ return ret == -1 ? ER_BACKUP_WRITE_LOC : ret;
if (m_with_compression)
{
@@ -474,7 +547,7 @@ bool Output_stream::open()
if (!(zbuf= (uchar*) my_malloc(ZBUF_SIZE, MYF(0))))
{
m_log.report_error(ER_OUTOFMEMORY, ZBUF_SIZE);
- return FALSE;
+ return ER_BACKUP_WRITE_LOC;
}
zstream.zalloc= 0;
zstream.zfree= 0;
@@ -488,15 +561,18 @@ bool Output_stream::open()
{
m_log.report_error(ER_BACKUP_FAILED_TO_INIT_COMPRESSION,
zerr, zstream.msg);
- return FALSE;
+ return ER_BACKUP_WRITE_LOC;
}
#else
m_log.report_error(ER_FEATURE_DISABLED, "compression", "--with-zlib-dir");
- return FALSE;
+ return ER_BACKUP_WRITE_LOC;
#endif
}
- return init();
+ if (!init())
+ return ER_BACKUP_WRITE_LOC;
+
+ return 0;
}
/**
@@ -627,23 +703,25 @@ bool Input_stream::init()
available for reading with stream_read(). Instead, they are stored in
m_header_buf member and examined by check_magic_and_version().
- @retval TRUE operation succeeded
- @retval FALSE operation failed
+ @retval 0 operation succeeded
+ @retval ER_OPTION_PREVENTS_STATEMENT secure-file-priv option
+ prevented stream open from this path
+ @retval ER_BACKUP_READ_LOC open failed for another reason
@todo Report errors.
*/
-bool Input_stream::open()
+int Input_stream::open()
{
close();
- bool ret= Stream::open();
+ int ret= Stream::open();
- if (!ret)
- return FALSE;
+ if (ret != 0)
+ return ret == -1 ? ER_BACKUP_READ_LOC : ret;
if (my_read(m_fd, m_header_buf, sizeof(m_header_buf),
MY_NABP /* error if not all bytes read */ ))
- return FALSE;
+ return ER_BACKUP_READ_LOC;
#ifdef HAVE_COMPRESS
if (!memcmp(m_header_buf, "\x1f\x8b\x08", 3))
@@ -653,7 +731,7 @@ bool Input_stream::open()
if (!(zbuf= (uchar*) my_malloc(ZBUF_SIZE, MYF(0))))
{
m_log.report_error(ER_OUTOFMEMORY, ZBUF_SIZE);
- return FALSE;
+ return ER_BACKUP_WRITE_LOC;
}
zstream.zalloc= 0;
zstream.zfree= 0;
@@ -666,18 +744,21 @@ bool Input_stream::open()
{
m_log.report_error(ER_GET_ERRMSG, zerr, zstream.msg, "inflateInit2");
my_free(zbuf, MYF(0));
- return FALSE;
+ return ER_BACKUP_READ_LOC;
}
m_with_compression= true;
blob.begin= m_header_buf;
blob.end= m_header_buf + 10;
if (stream_read((fd_stream*) this, &blob, blob) != BSTREAM_OK ||
blob.begin != blob.end)
- return FALSE;
+ return ER_BACKUP_READ_LOC;
}
#endif
- return init();
+ if (!init())
+ return ER_BACKUP_READ_LOC;
+
+ return 0;
}
/**
=== modified file 'sql/backup/stream.h'
--- a/sql/backup/stream.h 2008-08-08 17:21:31 +0000
+++ b/sql/backup/stream.h 2008-08-27 09:26:33 +0000
@@ -79,7 +79,7 @@ class Stream: public fd_stream
{
public:
- bool open();
+ int open();
virtual void close();
bool rewind();
@@ -109,6 +109,7 @@ private:
::String *backupdir);
int prepare_path(::String *backupdir,
LEX_STRING orig_loc);
+ bool test_secure_file_priv_access(char *path);
};
@@ -120,7 +121,7 @@ class Output_stream:
Output_stream(Logger&, ::String *, LEX_STRING, bool);
- bool open();
+ int open();
void close();
bool rewind();
@@ -138,7 +139,7 @@ class Input_stream:
Input_stream(Logger&, ::String *, LEX_STRING);
- bool open();
+ int open();
void close();
bool rewind();
| Thread |
|---|
| • bzr commit into mysql-6.0-backup branch (jorgen.loland:2683) Bug#34171 | Jorgen Loland | 27 Aug |