From cd9c0892d93af280065fae302b098ece1908d02e Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Fri, 21 May 2010 15:23:48 +0400 Subject: Bug #42064: low memory crash when importing hex strings, in Item_hex_string::Item_hex_string The status of memory allocation in the Lex_input_stream (called from the Parser_state constructor) was not checked which led to a parser crash in case of the out-of-memory error. The solution is to introduce new init() member function in Parser_state and Lex_input_stream so that status of memory allocation can be returned to the caller. mysql-test/r/error_simulation.result: Added a test case for bug #42064. mysql-test/t/error_simulation.test: Added a test case for bug #42064. mysys/my_alloc.c: Added error injection code for the regression test. mysys/my_malloc.c: Added error injection code for the regression test. mysys/safemalloc.c: Added error injection code for the regression test. sql/event_data_objects.cc: Use the new init() member function of Parser_state and check its return value to handle memory allocation failures. sql/mysqld.cc: Added error injection code for the regression test. sql/sp.cc: Use the new init() member function of Parser_state and check its return value to handle memory allocation failures. sql/sql_lex.cc: Moved memory allocation from constructor to the separate init() member function. Added error injection code for the regression test. sql/sql_lex.h: Moved memory allocation from constructor to the separate init() member function. sql/sql_parse.cc: Use the new init() member function of Parser_state and check its return value to handle memory allocation failures. sql/sql_partition.cc: Use the new init() member function of Parser_state and check its return value to handle memory allocation failures. sql/sql_prepare.cc: Use the new init() member function of Parser_state and check its return value to handle memory allocation failures. sql/sql_trigger.cc: Use the new init() member function of Parser_state and check its return value to handle memory allocation failures. sql/sql_view.cc: Use the new init() member function of Parser_state and check its return value to handle memory allocation failures.. sql/thr_malloc.cc: Added error injection code for the regression test. --- sql/sql_lex.cc | 50 +++++++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 29 deletions(-) (limited to 'sql/sql_lex.cc') diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index a3776f59241..35a5e2aeefc 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -110,39 +110,31 @@ st_parsing_options::reset() allows_derived= TRUE; } -Lex_input_stream::Lex_input_stream(THD *thd, - const char* buffer, - unsigned int length) -: m_thd(thd), - yylineno(1), - yytoklen(0), - yylval(NULL), - m_ptr(buffer), - m_tok_start(NULL), - m_tok_end(NULL), - m_end_of_query(buffer + length), - m_tok_start_prev(NULL), - m_buf(buffer), - m_buf_length(length), - m_echo(TRUE), - m_cpp_tok_start(NULL), - m_cpp_tok_start_prev(NULL), - m_cpp_tok_end(NULL), - m_body_utf8(NULL), - m_cpp_utf8_processed_ptr(NULL), - next_state(MY_LEX_START), - found_semicolon(NULL), - ignore_space(test(thd->variables.sql_mode & MODE_IGNORE_SPACE)), - stmt_prepare_mode(FALSE), - in_comment(NO_COMMENT), - m_underscore_cs(NULL) + +bool Lex_input_stream::init(THD *thd, const char *buff, unsigned int length) { + DBUG_EXECUTE_IF("bug42064_simulate_oom", + DBUG_SET("+d,simulate_out_of_memory");); + m_cpp_buf= (char*) thd->alloc(length + 1); + + DBUG_EXECUTE_IF("bug42064_simulate_oom", + DBUG_SET("-d,bug42064_simulate_oom");); + + if (m_cpp_buf == NULL) + return FALSE; + m_cpp_ptr= m_cpp_buf; -} + m_thd= thd; + m_ptr= buff; + m_end_of_query= buff + length; + m_buf= buff; + m_buf_length= length; + ignore_space= test(thd->variables.sql_mode & MODE_IGNORE_SPACE); + + return FALSE; + } -Lex_input_stream::~Lex_input_stream() -{} /** The operation is called from the parser in order to -- cgit v1.2.1 From fd4b3c6c1c7ee47af58e9abd84818809053b7c86 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Thu, 10 Jun 2010 17:45:22 -0300 Subject: Bug#42733: Type-punning warnings when compiling MySQL -- strict aliasing violations. One somewhat major source of strict-aliasing violations and related warnings is the SQL_LIST structure. For example, consider its member function `link_in_list` which takes a pointer to pointer of type T (any type) as a pointer to pointer to unsigned char. Dereferencing this pointer, which is done to reset the next field, violates strict-aliasing rules and might cause problems for surrounding code that uses the next field of the object being added to the list. The solution is to use templates to parametrize the SQL_LIST structure in order to deference the pointers with compatible types. As a side bonus, it becomes possible to remove quite a few casts related to acessing data members of SQL_LIST. sql/handler.h: Use the appropriate template type argument. sql/item.cc: Remove now-unnecessary cast. sql/item_subselect.cc: Remove now-unnecessary casts. sql/item_sum.cc: Use the appropriate template type argument. Remove now-unnecessary cast. sql/mysql_priv.h: Move SQL_LIST structure to sql_list.h Use the appropriate template type argument. sql/sp.cc: Remove now-unnecessary casts. sql/sql_delete.cc: Use the appropriate template type argument. Remove now-unnecessary casts. sql/sql_derived.cc: Remove now-unnecessary casts. sql/sql_lex.cc: Remove now-unnecessary casts. sql/sql_lex.h: SQL_LIST now takes a template type argument which must match the type of the elements of the list. Use forward declaration when the type is not available, it is used in pointers anyway. sql/sql_list.h: Rename SQL_LIST to SQL_I_List. The template parameter is the type of object that is stored in the list. sql/sql_olap.cc: Remove now-unnecessary casts. sql/sql_parse.cc: Remove now-unnecessary casts. sql/sql_prepare.cc: Remove now-unnecessary casts. sql/sql_select.cc: Remove now-unnecessary casts. sql/sql_show.cc: Remove now-unnecessary casts. sql/sql_table.cc: Remove now-unnecessary casts. sql/sql_trigger.cc: Remove now-unnecessary casts. sql/sql_union.cc: Remove now-unnecessary casts. sql/sql_update.cc: Remove now-unnecessary casts. sql/sql_view.cc: Remove now-unnecessary casts. sql/sql_yacc.yy: Remove now-unnecessary casts. storage/myisammrg/ha_myisammrg.cc: Remove now-unnecessary casts. --- sql/sql_lex.cc | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'sql/sql_lex.cc') diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index a3776f59241..7eb2607147c 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1641,7 +1641,7 @@ void st_select_lex::init_select() linkage= UNSPECIFIED_TYPE; order_list.elements= 0; order_list.first= 0; - order_list.next= (uchar**) &order_list.first; + order_list.next= &order_list.first; /* Set limit and offset to default values */ select_limit= 0; /* denotes the default limit = HA_POS_ERROR */ offset_limit= 0; /* denotes the default offset = 0 */ @@ -1963,7 +1963,7 @@ uint st_select_lex::get_in_sum_expr() TABLE_LIST* st_select_lex::get_table_list() { - return (TABLE_LIST*) table_list.first; + return table_list.first; } List* st_select_lex::get_item_list() @@ -2020,9 +2020,8 @@ void st_select_lex_unit::print(String *str, enum_query_type query_type) if (fake_select_lex->order_list.elements) { str->append(STRING_WITH_LEN(" order by ")); - fake_select_lex->print_order( - str, - (ORDER *) fake_select_lex->order_list.first, + fake_select_lex->print_order(str, + fake_select_lex->order_list.first, query_type); } fake_select_lex->print_limit(thd, str, query_type); @@ -2667,7 +2666,7 @@ TABLE_LIST *st_lex::unlink_first_table(bool *link_to_local) { select_lex.context.table_list= select_lex.context.first_name_resolution_table= first->next_local; - select_lex.table_list.first= (uchar*) (first->next_local); + select_lex.table_list.first= first->next_local; select_lex.table_list.elements--; //safety first->next_local= 0; /* @@ -2699,7 +2698,7 @@ TABLE_LIST *st_lex::unlink_first_table(bool *link_to_local) void st_lex::first_lists_tables_same() { - TABLE_LIST *first_table= (TABLE_LIST*) select_lex.table_list.first; + TABLE_LIST *first_table= select_lex.table_list.first; if (query_tables != first_table && first_table != 0) { TABLE_LIST *next; @@ -2746,9 +2745,9 @@ void st_lex::link_first_table_back(TABLE_LIST *first, if (link_to_local) { - first->next_local= (TABLE_LIST*) select_lex.table_list.first; + first->next_local= select_lex.table_list.first; select_lex.context.table_list= first; - select_lex.table_list.first= (uchar*) first; + select_lex.table_list.first= first; select_lex.table_list.elements++; //safety } } @@ -2914,7 +2913,7 @@ void st_select_lex::fix_prepare_information(THD *thd, Item **conds, prep_having= *having_conds; *having_conds= having= prep_having->copy_andor_structure(thd); } - fix_prepare_info_in_table_list(thd, (TABLE_LIST *)table_list.first); + fix_prepare_info_in_table_list(thd, table_list.first); } } -- cgit v1.2.1 From 6ada5e3fa9104b5138eea88e1064c246f08b49e6 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 15 Jul 2010 16:51:05 -0700 Subject: Fixed bug #603186. There were two problems that caused wrong results reported with this bug. 1. In some cases stored(persistent) virtual columns were not marked in the write_set and in the vcol_set bitmaps. 2. If the list of fields in an insert command was empty then the values of the stored virtual columns were set to default. To fix the first problem the function st_table::mark_virtual_columns_for_write was modified. Now the function has a parameter that says whether the virtual columns are to be marked for insert or for update. To fix the second problem a special handling of empty insert lists is added in the function fill_record(). --- sql/sql_lex.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'sql/sql_lex.cc') diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 51a87a3aa60..e380c94b58a 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1590,6 +1590,7 @@ void st_select_lex_unit::init_query() item_list.empty(); describe= 0; found_rows_for_union= 0; + insert_table_with_stored_vcol= 0; } void st_select_lex::init_query() -- cgit v1.2.1 From d7ad4352a1995b56693dea87135bb3107b917b91 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Jul 2010 11:00:57 +0800 Subject: BUG#49124 Security issue with /*!-versioned */ SQL statements on Slave /*![:version:] Query Code */, where [:version:] is a sequence of 5 digits representing the mysql server version(e.g /*!50200 ... */), is a special comment that the query in it can be executed on those servers whose versions are larger than the version appearing in the comment. It leads to a security issue when slave's version is larger than master's. A malicious user can improve his privileges on slaves. Because slave SQL thread is running with SUPER privileges, so it can execute queries that he/she does not have privileges on master. This bug is fixed with the logic below: - To replace '!' with ' ' in the magic comments which are not applied on master. So they become common comments and will not be applied on slave. - Example: 'INSERT INTO t1 VALUES (1) /*!10000, (2)*/ /*!99999 ,(3)*/ will be binlogged as 'INSERT INTO t1 VALUES (1) /*!10000, (2)*/ /* 99999 ,(3)*/ mysql-test/suite/rpl/t/rpl_conditional_comments.test: Test the patch for this bug. sql/mysql_priv.h: Rename inBuf as rawBuf and remove the const limitation. sql/sql_lex.cc: To replace '!' with ' ' in the magic comments which are not applied on master. sql/sql_lex.h: Remove the const limitation on parameter buff, as it can be modified in the function since this patch. Add member function yyUnput for Lex_input_stream. It set a character back the query buff. sql/sql_parse.cc: Rename inBuf as rawBuf and remove the const limitation. sql/sql_partition.cc: Remove the const limitation on parameter part_buff, as it can be modified in the function since this patch. sql/sql_partition.h: Remove the const limitation on parameter part_buff, as it can be modified in the function since this patch. sql/table.h: Remove the const limitation on variable partition_info, as it can be modified since this patch. --- sql/sql_lex.cc | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'sql/sql_lex.cc') diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 6bfd6f3906c..2bff036b1f1 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -111,7 +111,7 @@ st_parsing_options::reset() } -bool Lex_input_stream::init(THD *thd, const char *buff, unsigned int length) +bool Lex_input_stream::init(THD *thd, char *buff, unsigned int length) { DBUG_EXECUTE_IF("bug42064_simulate_oom", DBUG_SET("+d,simulate_out_of_memory");); @@ -1292,11 +1292,10 @@ int MYSQLlex(void *arg, void *yythd) ulong version; version=strtol(version_str, NULL, 10); - /* Accept 'M' 'm' 'm' 'd' 'd' */ - lip->yySkipn(5); - if (version <= MYSQL_VERSION_ID) { + /* Accept 'M' 'm' 'm' 'd' 'd' */ + lip->yySkipn(5); /* Expand the content of the special comment as real code */ lip->set_echo(TRUE); state=MY_LEX_START; @@ -1304,7 +1303,19 @@ int MYSQLlex(void *arg, void *yythd) } else { + const char* version_mark= lip->get_ptr() - 1; + DBUG_ASSERT(*version_mark == '!'); + /* + Patch and skip the conditional comment to avoid it + being propagated infinitely (eg. to a slave). + */ + char *pcom= lip->yyUnput(' '); comment_closed= ! consume_comment(lip, 1); + if (! comment_closed) + { + DBUG_ASSERT(pcom == version_mark); + *pcom= '!'; + } /* version allowed to have one level of comment inside. */ } } -- cgit v1.2.1 From 705ae3843272ac6e650e3349fec4035a57693f2e Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 30 Jul 2010 17:33:10 -0300 Subject: Bug#45288: pb2 returns a lot of compilation warnings on linux Fix compiler warnings. mysys/stacktrace.c: Tag unused parameters. sql/sql_lex.cc: Variable becomes unused in non-debug builds. Also, no need to assert the obvious. --- sql/sql_lex.cc | 3 --- 1 file changed, 3 deletions(-) (limited to 'sql/sql_lex.cc') diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 2bff036b1f1..24c51be2512 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1303,8 +1303,6 @@ int MYSQLlex(void *arg, void *yythd) } else { - const char* version_mark= lip->get_ptr() - 1; - DBUG_ASSERT(*version_mark == '!'); /* Patch and skip the conditional comment to avoid it being propagated infinitely (eg. to a slave). @@ -1313,7 +1311,6 @@ int MYSQLlex(void *arg, void *yythd) comment_closed= ! consume_comment(lip, 1); if (! comment_closed) { - DBUG_ASSERT(pcom == version_mark); *pcom= '!'; } /* version allowed to have one level of comment inside. */ -- cgit v1.2.1