diff options
author | Alexey Kopytov <Alexey.Kopytov@Sun.com> | 2010-05-07 20:17:55 +0400 |
---|---|---|
committer | Alexey Kopytov <Alexey.Kopytov@Sun.com> | 2010-05-07 20:17:55 +0400 |
commit | 9a2f98198903de89ab08ce7906e4307fe5ad50a9 (patch) | |
tree | 1cb84ff0f047fa8321330c5e4c52eca6424494de /sql | |
parent | 480a4852a01088cdc8638934f13469b6bf54effe (diff) | |
parent | 5b6ebdf086fe0506dc1d2cb70a95f9633fd7a782 (diff) | |
download | mariadb-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.cc | 3 | ||||
-rw-r--r-- | sql/mysqld.cc | 46 | ||||
-rw-r--r-- | sql/mysqld.h | 1 | ||||
-rw-r--r-- | sql/net_serv.cc | 4 | ||||
-rw-r--r-- | sql/sp_head.cc | 34 | ||||
-rw-r--r-- | sql/sp_head.h | 4 | ||||
-rw-r--r-- | sql/sql_class.cc | 3 | ||||
-rw-r--r-- | sql/sql_connect.cc | 7 | ||||
-rw-r--r-- | sql/sql_lex.cc | 1 | ||||
-rw-r--r-- | sql/sql_load.cc | 11 | ||||
-rw-r--r-- | sql/sql_select.cc | 3 |
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 } |