Problem:
=======
The return value from my_b_write is ignored by: `my_b_write_quoted',
`my_b_write_bit',`Query_log_event::print_query_header'
Most callers of `my_b_printf' ignore the return value. `log_event.cc'
has many calls to it.
Analysis:
========
`my_b_write' is used to write data into a file. If the write fails it
sets appropriate error number and error message through my_error()
function call and sets the IO_CACHE::error == -1.
`my_b_printf' function is also used to write data into a file, it
internally invokes my_b_write to do the write operation. Upon
success it returns number of characters written to file and on error
it returns -1 and sets the error through my_error() and also sets
IO_CACHE::error == -1. Most of the event specific print functions
for example `Create_file_log_event::print', `Execute_load_log_event::print'
etc are the ones which make several calls to the above two functions and
they do not check for the return value after the 'print' call. All the above
mentioned abuse cases deal with the client side.
Fix:
===
As part of bug fix a check for IO_CACHE::error == -1 has been added at
a very high level after the call to the 'print' function. There are
few more places where the return value of "my_b_write" is ignored
those are mentioned below.
+++ mysys/mf_iocache2.c 2012-06-04 07:03:15 +0000
@@ -430,7 +430,8 @@
memset(buffz, '0', minimum_width - length2);
else
memset(buffz, ' ', minimum_width - length2);
- my_b_write(info, buffz, minimum_width - length2);
+++ sql/log.cc 2012-06-08 09:04:46 +0000
@@ -2388,7 +2388,12 @@
{
end= strxmov(buff, "# administrator command: ", NullS);
buff_len= (ulong) (end - buff);
- my_b_write(&log_file, (uchar*) buff, buff_len);
At these places appropriate return value handlers have been added.
client/mysqlbinlog.cc:
check for IO_CACHE::error == -1 has been added after the call to
the event specific print functions
mysys/mf_iocache2.c:
Added handler to check the written value of `my_b_write'
sql/log.cc:
Added handler to check the written value of `my_b_write'
sql/log_event.cc:
Added error simulation statements in `Create_file_log_event::print`
and `Execute_load_query_log_event::print'
sql/rpl_utility.h:
Removed the extra ';'
HANDLE_FATAL_SIGNAL IN STRNLEN
Fixed the following bounds checking problems :
1. in check_if_legal_filename() make sure the null terminated
string is long enough before accessing the bytes in it.
Prevents pottential read-past-buffer-end
2. in my_wc_mb_filename() of the filename charset check
for the end of the destination buffer before sending single
byte characters into it.
Prevents write-past-end-of-buffer (and garbaling stack in
the cases reported here) errors.
Added test cases.
Problem: mysqlbinlog exits without any error code in case of
file write error. It is because of the fact that the calls
to Log_event::print() method does not return a value and the
thus any error were being ignored.
Resolution: We resolve this problem by checking for the
IO_CACHE::error == -1 after every call to Log_event:: print()
and terminating the further execution.
client/mysqlbinlog.cc:
- handled error conditions during event->print() calls
- added check for error in end_io_cache()
mysys/my_write.c:
Added debug code to simulate file write error.
error returned will be ENOSPC=> error no space on the disk
sql/log_event.cc:
Added debug code to simulate file write error, by reducing the size of io cache.
LOCK_THREAD_COUNT
When using the performance schema file io instrumentation in MySQL 5.5,
a thread would loop forever inside lf_pinbox_put_pins, when disconnecting.
It would also hold LOCK_thread_count while doing so, effectively killing the
server.
The root cause of the loop in lf_pinbox_put_pins() is a leak of LF_PINS,
when used with the filename_hash LF_HASH table in the performance schema.
This fix contains the following changes:
1)
Added the missing call to lf_hash_search_unpin(), to prevent the leak.
2)
In mysys/lf_alloc-pin.c, there was some extra debugging code
(MY_LF_EXTRA_DEBUG) written to detect precisely this kind of issues,
but it was never used.
Replaced MY_LF_EXTRA_DEBUG with DBUG_OFF, so that leaks similar to this one
can be always detected in regular debug builds.
3)
Backported the fix for the following bug, from 5.6 to 5.5:
Bug#13417446 - 63339: INCORRECT FILE PATH IN PEFORMANCE_SCHEMA ON WINDOWS
storage/innobase/include/sync0rw.ic:
Prerequisite for compiling with gcc4 on solaris: ignore result from
os_compare_and_swap_ulint
storage/myisam/mi_dynrec.c:
Prerequisite for compiling with gcc4 on solaris: cast to void*
There are two threads. In one thread, dml operation is going on
involving cascaded update operation. In another thread, alter
table add foreign key constraint is happening. Under these
circumstances, it is possible for the dml thread to access a
dict_foreign_t object that has been freed by the ddl thread.
The debug sync test case provides the sequence of operations.
Without fix, the test case will crash the server (because of
newly added assert). With fix, the alter table stmt will return
an error message.
Backporting the fix from MySQL 5.5 to 5.1
rb:961
rb:947
There are two threads. In one thread, dml operation is going on
involving cascaded update operation. In another thread, alter
table add foreign key constraint is happening. Under these
circumstances, it is possible for the dml thread to access a
dict_foreign_t object that has been freed by the ddl thread.
The debug sync test case provides the sequence of operations.
Without fix, the test case will crash the server (because of
newly added assert). With fix, the alter table stmt will return
an error message.
rb:947
approved by Jimmy Yang
Introducing new collations:
utf8_general_mysql500_ci and ucs2_general_mysql500_ci,
to reproduce behaviour of utf8_general_ci and ucs2_general_ci
from mysql-5.1.23 (and earlier).
The collations are added to simplify upgrade from mysql-5.1.23 and earlier.
Note: The patch does not make new server start over old data automatically.
Some manual upgrade procedures are assumed.
Paul: please get in touch with me to discuss upgrade procedures
when documenting this bug.
modified:
include/m_ctype.h
mysql-test/r/ctype_utf8.result
mysql-test/t/ctype_utf8.test
mysys/charset-def.c
strings/ctype-ucs2.c
strings/ctype-utf8.c
handle_segfault is the signal handler code of mysqld. however, it makes
calls to potentially unsafe functions localtime_r, fprintf, fflush.
include/my_stacktrace.h:
Add safe versions of itoa() write() and snprintf().
libmysqld/CMakeLists.txt:
Move signal handler to separate file.
mysys/stacktrace.c:
Remove unsafe function calls.
sql/CMakeLists.txt:
Move signal handler to separate file.
sql/mysqld.cc:
Move signal handler to separate file.
sql/set_var.h:
Add missing #include dependency.
sql/sys_vars.cc:
Cleanup .h and .cc files.
sql/sys_vars.h:
Cleanup .h and .cc files.
handle_segfault is the signal handler code of mysqld. however, it makes
calls to potentially unsafe functions localtime_r, fprintf, fflush.
include/my_stacktrace.h:
Add safe versions of itoa() write() and snprintf().
libmysqld/CMakeLists.txt:
Move signal handler to separate file.
mysys/stacktrace.c:
Remove unsafe function calls.
sql/CMakeLists.txt:
Move signal handler to separate file.
sql/Makefile.am:
Move signal handler to separate file.
sql/mysqld.cc:
Move signal handler to separate file.
sql/signal_handler.cc:
Remove unsafe function calls.
This fix was accidentally pushed to mysql-5.1 after the 5.1.59 clone-off in
bzr revision id marko.makela@oracle.com-20110829081642-z0w992a0mrc62s6w
with the fix of Bug#12704861 Corruption after a crash during BLOB update
but not merged to mysql-5.5 and upwards.
In the Barracuda formats, the clustered index record no longer
contains a prefix of off-page columns. Because of this, the undo log
must contain these prefixes, so that purge and multi-versioning will
continue to work. However, this also means that an undo log record can
become too big to fit in an undo log page. (It is a limitation of the
undo log that undo records cannot span across multiple pages.)
In case the checks for undo log size fail when CREATE TABLE or CREATE
INDEX is executed, we need a fallback that blocks a modification
operation when the undo log record would exceed the maximum size.
trx_undo_free_last_page_func(): Renamed from trx_undo_free_page_in_rollback().
Define the trx_t parameter only in debug builds.
trx_undo_free_last_page(): Wrapper for trx_undo_free_last_page_func().
Pass the trx_t parameter only in debug builds.
trx_undo_truncate_end_func(): Renamed from trx_undo_truncate_end().
Define the trx_t parameter only in debug builds. Rewrite a for(;;) loop
as a while loop for clarity.
trx_undo_truncate_end(): Wrapper for from trx_undo_truncate_end_func().
Pass the trx_t parameter only in debug builds.
trx_undo_erase_page_end(): Return TRUE if the page was non-empty
to begin with. Refuse to erase empty pages.
trx_undo_report_row_operation(): If the page for which the undo log
was too big was empty, free the undo page and return DB_TOO_BIG_RECORD.
rb:749 approved by Inaam Rana
Also addressed issues in bug #11745133, where we could mark a table
corrupted instead of crashing the server when found a corrupted buffer/page
if the table created with innodb_file_per_table on.
FUNCTION 'PTHREAD_INIT'
The problem was that compilation would fail with a warning:
Implicit declaration of function 'pthread_init' if MySQL was
compiled on OS X 10.7 (Lion). The reason was that pthread_init()
is now part of an internal OS X pthread library so it was found
by CMake.
This patch fixes the problem by removing HAVE_PTHREAD_INIT and
related code. pthread_init() was specific to MIT-pthreads which
has not been supported since 4.1 and was therefore no longer
relevant.
No test case added.
With this change, the index prefix column length lifted from 767 bytes
to 3072 bytes if "innodb_large_prefix" is set to "true".
rb://603 approved by Marko
can't parse relative paths "higher" than 3 levels up
When trying to LOAD DATA LOCAL INFILE using a relative path with 3 or
more levels up in the directory hierarchy, mysqld wrongly parses
the path and as a consequence, can't find the file.
This bug was introduced by patch for bug#58205.
The reason for bug is that implementaiton of function cleanup_dirname()
doesn't take into account the begin of buffer being processed during
handling of path to file.
mysys/mf_pack.c:
function cleanup_dirname() was modified: fixed wrong comparison
condition when handling substring "../" at the begining of the buffer.
Before this fix, a thread instrumented for the performance schema,
that would perform file io operations, could crash inside the LF_HASH
implementation, in cases when my_thread_init is not called.
The crash itself has not been reported in 5.5 but similar crashes have
been found in 5.6-based development branches, using LF_HASH for
more instrumentation.
The possibility of a crash in 5.5 is confirmed by code analysis.
The problem is that, when my_thread_init() is not called,
which can happen for threads in storage engines or thirs party code,
my_thread_var is NULL.
Using my_thread_var->stacks_ends_here in mysys/lf_alloc-pin.c is unsafe.
Given that my_thread_var is used:
- only for stacks_ends_here
- only on platform with HAVE_ALLOCA
- only when there is enough room on the stack
and given that the LF_HASH implementation has a fallback
algorythm implemented already when using alloca is not possible,
using my_thread_var->stacks_ends_here is in fact not a strict requirement,
and can be relaxed.
The fix is to:
- test explicitly if my_thread_var is NULL, to account for cases
when my_thread_init() is not used by the calling thread.
- not use alloca in this case, and rely on the fall back code already in place.
so that the LF_HASH can be supported even without my_thread_init().
The implementation of mysys/lf_alloc-pin.c has been fixed to support this new usage.
The units tests in unittest/mysys/lf-t.c have been adjusted accordingly.
USING '..' ON WINDOWS
Backport of the fix to 5.0 (to be null-merged to 5.1).
Moved the test into the main test suite.
Made mysql-test-run.pl to not use symlinks for sdtdata as the symlinks
are now properly recognized by secure_file_priv.
Made sure the paths in load_file(), LOAD DATA and SELECT .. INTO OUTFILE
that are checked against secure_file_priv in a correct way similarly to 5.1
by the extended is_secure_file_path() backport before the comparison.
Added an extensive test with all the variants of upper/lower case,
slash/backslash and case sensitivity.
Added few comments to the code.
on lctn2 systems
There was a local variable in get_all_tables() to store the
"original" value of the database name as it can get lowercased
depending on the lower_case_table_name value.
get_all_tables() iterates over database names and for each
database iterates over the tables in it.
The "original" db name was assigned in the table names loop.
Thus the first table is ok, but the second and subsequent tables
get the lowercased name from processing the first table.
Fixed by moving the assignment of the original database name
from the inner (table name) to the outer (database name) loop.
Test suite added.
The LGPL license is used in some legacy code, and to
adhere to current licensing polity, we remove those
files that are no longer used, and reorganize the
remaining LGPL code so it will be GPL licensed from
now on.
Note: This patch only removed LGPL licensed files
in MySQL 5.5 and later, and is the third of a
set of patches to remove LGPL from all trees.
(See Bug# 11840513 for details)
The LGPL license is used in some legacy code, and to
adhere to current licensing polity, we remove those
files that are no longer used, and reorganize the
remaining LGPL code so it will be GPL licensed from
now on.
Note: This patch only removed LGPL licensed files
in MySQL 5.1, and is the second of a set of
patches to remove LGPL from all trees.
(See Bug# 11840513 for details)