1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-07 00:04:31 +03:00

Manual merge of mysql-5.1-bugteam to mysql-trunk-merge.

Conflicts:

Text conflict in mysql-test/r/explain.result
Text conflict in mysql-test/t/explain.test
Text conflict in sql/net_serv.cc
Text conflict in sql/sp_head.cc
Text conflict in sql/sql_priv.h
This commit is contained in:
Alexey Kopytov
2010-05-07 20:17:55 +04:00
19 changed files with 181 additions and 59 deletions

View File

@@ -300,6 +300,16 @@ typedef struct st_net {
/** Client library sqlstate buffer. Set along with the error message. */ /** Client library sqlstate buffer. Set along with the error message. */
char sqlstate[SQLSTATE_LENGTH+1]; char sqlstate[SQLSTATE_LENGTH+1];
void *extension; void *extension;
#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
/*
Controls whether a big packet should be skipped.
Initially set to FALSE by default. Unauthenticated sessions must have
this set to FALSE so that the server can't be tricked to read packets
indefinitely.
*/
my_bool skip_big_packet;
#endif
} NET; } NET;

View File

@@ -246,4 +246,16 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings: Warnings:
Note 1003 select '1' AS `f1`,`test`.`t2`.`f2` AS `f2` from `test`.`t2` where (`test`.`t2`.`f2` = 1) Note 1003 select '1' AS `f1`,`test`.`t2`.`f2` AS `f2` from `test`.`t2` where (`test`.`t2`.`f2` = 1)
drop table t1,t2; drop table t1,t2;
#
# Bug #48419: another explain crash..
#
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (b BLOB, KEY b(b(100)));
INSERT INTO t2 VALUES ('1'), ('2'), ('3');
FLUSH TABLES;
EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT 1 FROM t1 t JOIN t2 WHERE b <= 1 AND t.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
DROP TABLE t1, t2;
End of 5.1 tests. End of 5.1 tests.

View File

@@ -202,12 +202,6 @@ select * from t1;
a b c a b c
10 NULL Ten 10 NULL Ten
15 NULL Fifteen 15 NULL Fifteen
show variables like "secure_file_pri%";
Variable_name Value
secure_file_priv MYSQLTEST_VARDIR
select @@secure_file_priv;
@@secure_file_priv
MYSQLTEST_VARDIR
set @@secure_file_priv= 0; set @@secure_file_priv= 0;
ERROR HY000: Variable 'secure_file_priv' is a read only variable ERROR HY000: Variable 'secure_file_priv' is a read only variable
truncate table t1; truncate table t1;

View File

@@ -155,24 +155,24 @@ execute stmt1 ;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table 6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
5 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found 5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
4 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found 4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
execute stmt1 ; execute stmt1 ;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table 6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
5 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found 5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
4 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found 4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25; explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table 6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
5 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found 5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
4 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found 4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
deallocate prepare stmt1; deallocate prepare stmt1;

View File

@@ -2128,6 +2128,29 @@ Warning 1048 Column 'id' cannot be null
Warning 1048 Column 'id' cannot be null Warning 1048 Column 'id' cannot be null
DROP TRIGGER t1_bu; DROP TRIGGER t1_bu;
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# Bug#50755: Crash if stored routine def contains version comments
#
DROP DATABASE IF EXISTS db1;
DROP TRIGGER IF EXISTS trg1;
DROP TABLE IF EXISTS t1, t2;
CREATE DATABASE db1;
USE db1;
CREATE TABLE t1 (b INT);
CREATE TABLE t2 (a INT);
CREATE TRIGGER trg1 BEFORE INSERT ON t2 FOR EACH ROW INSERT/*!INTO*/t1 VALUES (1);
# Used to crash
SHOW TRIGGERS IN db1;
Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
Warnings:
Warning 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VALUES (1)' at line 1
INSERT INTO t2 VALUES (1);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VALUES (1)' at line 1
SELECT * FROM t1;
b
# Work around Bug#45235
DROP DATABASE db1;
USE test;
End of 5.1 tests. End of 5.1 tests.
# #
# Bug#34453 Can't change size of file (Errcode: 1224) # Bug#34453 Can't change size of file (Errcode: 1224)

View File

@@ -210,4 +210,17 @@ explain extended select * from t1 where f1=1;
explain extended select * from t1 join t2 on f1=f2 where f1=1; explain extended select * from t1 join t2 on f1=f2 where f1=1;
drop table t1,t2; drop table t1,t2;
--echo #
--echo # Bug #48419: another explain crash..
--echo #
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (b BLOB, KEY b(b(100)));
INSERT INTO t2 VALUES ('1'), ('2'), ('3');
FLUSH TABLES;
EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT 1 FROM t1 t JOIN t2 WHERE b <= 1 AND t.a);
DROP TABLE t1, t2;
--echo End of 5.1 tests. --echo End of 5.1 tests.

View File

@@ -153,10 +153,16 @@ select * from t1;
# #
# It should not be possible to load from a file outside of vardir # It should not be possible to load from a file outside of vardir
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ## The following lines were disabled because of patch for
show variables like "secure_file_pri%"; ## bug 50373. MYSQLTEST_VARDIR doesn't rewrite symlinks
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ## to real paths, but this is done for secure_file_priv.
select @@secure_file_priv; ## Because of this the result can't be replaced if the
## test suite runs with the --mem option which creates
## symlinks to the ramdisk.
#--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
#show variables like "secure_file_pri%";
#--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
#select @@secure_file_priv;
--error 1238 --error 1238
set @@secure_file_priv= 0; set @@secure_file_priv= 0;

View File

@@ -2439,6 +2439,37 @@ UPDATE t1 SET id=NULL;
DROP TRIGGER t1_bu; DROP TRIGGER t1_bu;
DROP TABLE t1,t2; DROP TABLE t1,t2;
--echo #
--echo # Bug#50755: Crash if stored routine def contains version comments
--echo #
--disable_warnings
DROP DATABASE IF EXISTS db1;
DROP TRIGGER IF EXISTS trg1;
DROP TABLE IF EXISTS t1, t2;
--enable_warnings
CREATE DATABASE db1;
USE db1;
CREATE TABLE t1 (b INT);
CREATE TABLE t2 (a INT);
CREATE TRIGGER trg1 BEFORE INSERT ON t2 FOR EACH ROW INSERT/*!INTO*/t1 VALUES (1);
--echo # Used to crash
SHOW TRIGGERS IN db1;
--error ER_PARSE_ERROR
INSERT INTO t2 VALUES (1);
SELECT * FROM t1;
--echo # Work around Bug#45235
let $MYSQLD_DATADIR = `select @@datadir`;
--remove_file $MYSQLD_DATADIR/db1/t2.TRG
--remove_file $MYSQLD_DATADIR/db1/trg1.TRN
DROP DATABASE db1;
USE test;
--echo End of 5.1 tests. --echo End of 5.1 tests.

View File

@@ -3192,8 +3192,7 @@ String *Item_load_file::val_str(String *str)
MY_RELATIVE_PATH | MY_UNPACK_FILENAME); MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
/* Read only allowed from within dir specified by secure_file_priv */ /* Read only allowed from within dir specified by secure_file_priv */
if (opt_secure_file_priv && if (!is_secure_file_path(path))
strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
goto err; goto err;
if (!mysql_file_stat(key_file_loadfile, path, &stat_info, MYF(0))) if (!mysql_file_stat(key_file_loadfile, path, &stat_info, MYF(0)))

View File

@@ -7711,6 +7711,45 @@ fn_format_relative_to_data_home(char * to, const char *name,
} }
/**
Test a file path to determine if the path is compatible with the secure file
path restriction.
@param path null terminated character string
@return
@retval TRUE The path is secure
@retval FALSE The path isn't secure
*/
bool is_secure_file_path(char *path)
{
char buff1[FN_REFLEN], buff2[FN_REFLEN];
/*
All paths are secure if opt_secure_file_path is 0
*/
if (!opt_secure_file_priv)
return TRUE;
if (my_realpath(buff1, path, 0))
{
/*
The supplied file path might have been a file and not a directory.
*/
int length= (int)dirname_length(path);
if (length >= FN_REFLEN)
return FALSE;
memcpy(buff2, path, length);
buff2[length]= '\0';
if (length == 0 || my_realpath(buff1, buff2, 0))
return FALSE;
}
convert_dirname(buff2, buff1, NullS);
if (strncmp(opt_secure_file_priv, buff2, strlen(opt_secure_file_priv)))
return FALSE;
return TRUE;
}
static int fix_paths(void) static int fix_paths(void)
{ {
char buff[FN_REFLEN],*pos; char buff[FN_REFLEN],*pos;
@@ -7777,14 +7816,13 @@ static int fix_paths(void)
} }
else else
{ {
convert_dirname(buff, opt_secure_file_priv, NullS); if (my_realpath(buff, opt_secure_file_priv, 0))
char *secure_file_real_path= (char *)my_malloc(FN_REFLEN, MYF(MY_FAE));
if (secure_file_real_path == 0 ||
my_realpath(secure_file_real_path, buff, 0))
{ {
sql_print_warning("Failed to normalize the argument for --secure-file-priv."); sql_print_warning("Failed to normalize the argument for --secure-file-priv.");
return 1; return 1;
} }
char *secure_file_real_path= (char *)my_malloc(FN_REFLEN, MYF(MY_FAE));
convert_dirname(secure_file_real_path, buff, NullS);
my_free(opt_secure_file_priv, MYF(0)); my_free(opt_secure_file_priv, MYF(0));
opt_secure_file_priv= secure_file_real_path; opt_secure_file_priv= secure_file_real_path;
} }

View File

@@ -71,6 +71,7 @@ void unlink_thd(THD *thd);
bool one_thread_per_connection_end(THD *thd, bool put_in_cache); bool one_thread_per_connection_end(THD *thd, bool put_in_cache);
void flush_thread_cache(); void flush_thread_cache();
void refresh_status(THD *thd); void refresh_status(THD *thd);
bool is_secure_file_path(char *path);
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *system_charset_info; extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *system_charset_info;
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *files_charset_info ; extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *files_charset_info ;

View File

@@ -133,6 +133,9 @@ my_bool my_net_init(NET *net, Vio* vio)
net->where_b = net->remain_in_buf=0; net->where_b = net->remain_in_buf=0;
net->last_errno=0; net->last_errno=0;
net->unused= 0; net->unused= 0;
#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
net->skip_big_packet= FALSE;
#endif
if (vio != 0) /* If real connection */ if (vio != 0) /* If real connection */
{ {
@@ -967,6 +970,7 @@ my_real_read(NET *net, size_t *complen)
{ {
#if defined(MYSQL_SERVER) && !defined(NO_ALARM) #if defined(MYSQL_SERVER) && !defined(NO_ALARM)
if (!net->compress && if (!net->compress &&
net->skip_big_packet &&
!my_net_skip_rest(net, (uint32) len, &alarmed, &alarm_buff)) !my_net_skip_rest(net, (uint32) len, &alarmed, &alarm_buff))
net->error= 3; /* Successfully skiped packet */ net->error= 3; /* Successfully skiped packet */
#endif #endif

View File

@@ -747,21 +747,12 @@ create_typelib(MEM_ROOT *mem_root, Create_field *field_def, List<String> *src)
sp_head::~sp_head() sp_head::~sp_head()
{ {
DBUG_ENTER("sp_head::~sp_head");
destroy();
delete m_next_cached_sp;
if (m_thd)
restore_thd_mem_root(m_thd);
DBUG_VOID_RETURN;
}
void
sp_head::destroy()
{
sp_instr *i;
LEX *lex; LEX *lex;
DBUG_ENTER("sp_head::destroy"); sp_instr *i;
DBUG_PRINT("info", ("name: %s", m_name.str)); DBUG_ENTER("sp_head::~sp_head");
/* sp_head::restore_thd_mem_root() must already have been called. */
DBUG_ASSERT(m_thd == NULL);
for (uint ip = 0 ; (i = get_instr(ip)) ; ip++) for (uint ip = 0 ; (i = get_instr(ip)) ; ip++)
delete i; delete i;
@@ -772,21 +763,22 @@ sp_head::destroy()
/* /*
If we have non-empty LEX stack then we just came out of parser with If we have non-empty LEX stack then we just came out of parser with
error. Now we should delete all auxilary LEXes and restore original error. Now we should delete all auxilary LEXes and restore original
THD::lex (In this case sp_head::restore_thd_mem_root() was not called THD::lex. It is safe to not update LEX::ptr because further query
too, so m_thd points to the current thread context). string parsing and execution will be stopped anyway.
It is safe to not update LEX::ptr because further query string parsing
and execution will be stopped anyway.
*/ */
DBUG_ASSERT(m_lex.is_empty() || m_thd);
while ((lex= (LEX *)m_lex.pop())) while ((lex= (LEX *)m_lex.pop()))
{ {
lex_end(m_thd->lex); THD *thd= lex->thd;
delete m_thd->lex; lex_end(thd->lex);
m_thd->lex= lex; delete thd->lex;
thd->lex= lex;
} }
my_hash_free(&m_sptabs); my_hash_free(&m_sptabs);
my_hash_free(&m_sroutines); my_hash_free(&m_sroutines);
delete m_next_cached_sp;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }

View File

@@ -305,10 +305,6 @@ public:
virtual ~sp_head(); virtual ~sp_head();
/// Free memory
void
destroy();
bool bool
execute_trigger(THD *thd, execute_trigger(THD *thd,
const LEX_STRING *db_name, const LEX_STRING *db_name,

View File

@@ -1917,8 +1917,7 @@ static File create_file(THD *thd, char *path, sql_exchange *exchange,
else else
(void) fn_format(path, exchange->file_name, mysql_real_data_home, "", option); (void) fn_format(path, exchange->file_name, mysql_real_data_home, "", option);
if (opt_secure_file_priv && if (!is_secure_file_path(path))
strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
{ {
/* Write only allowed to dir or subdir specified by secure_file_priv */ /* Write only allowed to dir or subdir specified by secure_file_priv */
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv"); my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");

View File

@@ -496,6 +496,13 @@ check_user(THD *thd, enum enum_server_command command,
} }
my_ok(thd); my_ok(thd);
thd->password= test(passwd_len); // remember for error messages thd->password= test(passwd_len); // remember for error messages
/*
Allow the network layer to skip big packets. Although a malicious
authenticated session might use this to trick the server to read
big packets indefinitely, this is a previously established behavior
that needs to be preserved as to not break backwards compatibility.
*/
thd->net.skip_big_packet= TRUE;
/* Ready to handle queries */ /* Ready to handle queries */
DBUG_RETURN(0); DBUG_RETURN(0);
} }

View File

@@ -2194,6 +2194,7 @@ void LEX::cleanup_lex_after_parse_error(THD *thd)
*/ */
if (thd->lex->sphead) if (thd->lex->sphead)
{ {
thd->lex->sphead->restore_thd_mem_root(thd);
delete thd->lex->sphead; delete thd->lex->sphead;
thd->lex->sphead= NULL; thd->lex->sphead= NULL;
} }

View File

@@ -394,15 +394,12 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
DBUG_ASSERT(FALSE); DBUG_ASSERT(FALSE);
#endif #endif
} }
else if (opt_secure_file_priv) else if (!is_secure_file_path(name))
{
if (strncmp(opt_secure_file_priv, name, strlen(opt_secure_file_priv)))
{ {
/* Read only allowed from within dir specified by secure_file_priv */ /* Read only allowed from within dir specified by secure_file_priv */
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv"); my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
}
} }
if ((file= mysql_file_open(key_file_load, if ((file= mysql_file_open(key_file_load,

View File

@@ -1127,8 +1127,7 @@ JOIN::optimize()
} }
if (conds && const_table_map != found_const_table_map && if (conds && const_table_map != found_const_table_map &&
(select_options & SELECT_DESCRIBE) && (select_options & SELECT_DESCRIBE))
select_lex->master_unit() == &thd->lex->unit) // upper level SELECT
{ {
conds=new Item_int((longlong) 0,1); // Always false conds=new Item_int((longlong) 0,1); // Always false
} }