summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorAlexey Kopytov <Alexey.Kopytov@Sun.com>2010-05-07 20:17:55 +0400
committerAlexey Kopytov <Alexey.Kopytov@Sun.com>2010-05-07 20:17:55 +0400
commit9a2f98198903de89ab08ce7906e4307fe5ad50a9 (patch)
tree1cb84ff0f047fa8321330c5e4c52eca6424494de /sql
parent480a4852a01088cdc8638934f13469b6bf54effe (diff)
parent5b6ebdf086fe0506dc1d2cb70a95f9633fd7a782 (diff)
downloadmariadb-git-9a2f98198903de89ab08ce7906e4307fe5ad50a9.tar.gz
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
Diffstat (limited to 'sql')
-rw-r--r--sql/item_strfunc.cc3
-rw-r--r--sql/mysqld.cc46
-rw-r--r--sql/mysqld.h1
-rw-r--r--sql/net_serv.cc4
-rw-r--r--sql/sp_head.cc34
-rw-r--r--sql/sp_head.h4
-rw-r--r--sql/sql_class.cc3
-rw-r--r--sql/sql_connect.cc7
-rw-r--r--sql/sql_lex.cc1
-rw-r--r--sql/sql_load.cc11
-rw-r--r--sql/sql_select.cc3
11 files changed, 75 insertions, 42 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 15ac6e24b16..61febb01e93 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -3192,8 +3192,7 @@ String *Item_load_file::val_str(String *str)
MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
/* Read only allowed from within dir specified by secure_file_priv */
- if (opt_secure_file_priv &&
- strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
+ if (!is_secure_file_path(path))
goto err;
if (!mysql_file_stat(key_file_loadfile, path, &stat_info, MYF(0)))
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 2c90aa8fbf5..950ba55a5bd 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -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)
{
char buff[FN_REFLEN],*pos;
@@ -7777,14 +7816,13 @@ static int fix_paths(void)
}
else
{
- convert_dirname(buff, opt_secure_file_priv, NullS);
- 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))
+ if (my_realpath(buff, opt_secure_file_priv, 0))
{
sql_print_warning("Failed to normalize the argument for --secure-file-priv.");
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));
opt_secure_file_priv= secure_file_real_path;
}
diff --git a/sql/mysqld.h b/sql/mysqld.h
index 8770e273445..9a6e43e4321 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -71,6 +71,7 @@ void unlink_thd(THD *thd);
bool one_thread_per_connection_end(THD *thd, bool put_in_cache);
void flush_thread_cache();
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 *files_charset_info ;
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index fc8655ea2e7..28ed4cbdbaf 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -133,6 +133,9 @@ my_bool my_net_init(NET *net, Vio* vio)
net->where_b = net->remain_in_buf=0;
net->last_errno=0;
net->unused= 0;
+#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
+ net->skip_big_packet= FALSE;
+#endif
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 (!net->compress &&
+ net->skip_big_packet &&
!my_net_skip_rest(net, (uint32) len, &alarmed, &alarm_buff))
net->error= 3; /* Successfully skiped packet */
#endif
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index dee01ee0b62..e833a540032 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -747,21 +747,12 @@ create_typelib(MEM_ROOT *mem_root, Create_field *field_def, List<String> *src)
sp_head::~sp_head()
{
+ LEX *lex;
+ sp_instr *i;
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;
- DBUG_ENTER("sp_head::destroy");
- DBUG_PRINT("info", ("name: %s", m_name.str));
+ /* 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++)
delete i;
@@ -772,21 +763,22 @@ sp_head::destroy()
/*
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
- THD::lex (In this case sp_head::restore_thd_mem_root() was not called
- too, so m_thd points to the current thread context).
- It is safe to not update LEX::ptr because further query string parsing
- and execution will be stopped anyway.
+ THD::lex. 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()))
{
- lex_end(m_thd->lex);
- delete m_thd->lex;
- m_thd->lex= lex;
+ THD *thd= lex->thd;
+ lex_end(thd->lex);
+ delete thd->lex;
+ thd->lex= lex;
}
my_hash_free(&m_sptabs);
my_hash_free(&m_sroutines);
+
+ delete m_next_cached_sp;
+
DBUG_VOID_RETURN;
}
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 165f88321a9..539a2da5f8c 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -305,10 +305,6 @@ public:
virtual ~sp_head();
- /// Free memory
- void
- destroy();
-
bool
execute_trigger(THD *thd,
const LEX_STRING *db_name,
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index f59ffd4d42f..914ef5c919a 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1917,8 +1917,7 @@ static File create_file(THD *thd, char *path, sql_exchange *exchange,
else
(void) fn_format(path, exchange->file_name, mysql_real_data_home, "", option);
- if (opt_secure_file_priv &&
- strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
+ if (!is_secure_file_path(path))
{
/* Write only allowed to dir or subdir specified by secure_file_priv */
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index e2d0977def7..c0081c13366 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -496,6 +496,13 @@ check_user(THD *thd, enum enum_server_command command,
}
my_ok(thd);
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 */
DBUG_RETURN(0);
}
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 13f85b24299..f44edfdf6fb 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -2194,6 +2194,7 @@ void LEX::cleanup_lex_after_parse_error(THD *thd)
*/
if (thd->lex->sphead)
{
+ thd->lex->sphead->restore_thd_mem_root(thd);
delete thd->lex->sphead;
thd->lex->sphead= NULL;
}
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 77068f3d83b..59d30b020e8 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -394,14 +394,11 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
DBUG_ASSERT(FALSE);
#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 */
- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
- DBUG_RETURN(TRUE);
- }
+ /* Read only allowed from within dir specified by secure_file_priv */
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
+ DBUG_RETURN(TRUE);
}
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index e8809564bce..21178f828c1 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1127,8 +1127,7 @@ JOIN::optimize()
}
if (conds && const_table_map != found_const_table_map &&
- (select_options & SELECT_DESCRIBE) &&
- select_lex->master_unit() == &thd->lex->unit) // upper level SELECT
+ (select_options & SELECT_DESCRIBE))
{
conds=new Item_int((longlong) 0,1); // Always false
}