summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorLibing Song <libing.song@oracle.com>2012-12-01 08:04:33 +0800
committerLibing Song <libing.song@oracle.com>2012-12-01 08:04:33 +0800
commitbdfc4dc6c6927d4dc46e3cd0c4ff2a1595c174a3 (patch)
tree408f9151a5cb69548a222204559122904e2a7837 /sql
parent60fff18d774518fbca00961c9511f3ea1bd177f2 (diff)
downloadmariadb-git-bdfc4dc6c6927d4dc46e3cd0c4ff2a1595c174a3.tar.gz
Bug#11764602 ASSERTION IN
FORMAT_DESCRIPTION_LOG_EVENT::CALC_SERVER_VERSION_SPLIT Problem: When reading a Format_description_log_event, it supposes MySQL version is always valid and DBUG_ASSERTION is used check the version number. However, user may give a wrong binlog offset, even give a faked binary event which includes an invalid MySQL version. This will cause server crash. Fix: The assertions are removed and an error will be reported if MySQL version in Format_description_log_event is invalid.
Diffstat (limited to 'sql')
-rw-r--r--sql/log_event.cc18
-rw-r--r--sql/log_event.h18
2 files changed, 30 insertions, 6 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 58de0d310d7..63770e340b0 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -4205,7 +4205,6 @@ Format_description_log_event::do_shall_skip(Relay_log_info *rli)
into 'server_version_split':
X.Y.Zabc (X,Y,Z numbers, a not a digit) -> {X,Y,Z}
X.Yabc -> {X,Y,0}
- Xabc -> {X,0,0}
'server_version_split' is then used for lookups to find if the server which
created this event has some known bug.
*/
@@ -4216,10 +4215,21 @@ void Format_description_log_event::calc_server_version_split()
for (uint i= 0; i<=2; i++)
{
number= strtoul(p, &r, 10);
- server_version_split[i]= (uchar)number;
- DBUG_ASSERT(number < 256); // fit in uchar
+ /*
+ It is an invalid version if any version number greater than 255 or
+ first number is not followed by '.'.
+ */
+ if (number < 256 && (*r == '.' || i != 0))
+ server_version_split[i]= (uchar)number;
+ else
+ {
+ server_version_split[0]= 0;
+ server_version_split[1]= 0;
+ server_version_split[2]= 0;
+ break;
+ }
+
p= r;
- DBUG_ASSERT(!((i == 0) && (*r != '.'))); // should be true in practice
if (*r == '.')
p++; // skip the dot
}
diff --git a/sql/log_event.h b/sql/log_event.h
index c36564fcde8..4c8580eb2fd 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -969,7 +969,7 @@ public:
return thd ? thd->db : 0;
}
#else
- Log_event() : temp_buf(0) {}
+ Log_event() : temp_buf(0), flags(0) {}
/* avoid having to link mysqlbinlog against libpthread */
static Log_event* read_log_event(IO_CACHE* file,
const Format_description_log_event
@@ -2244,12 +2244,26 @@ public:
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
- bool is_valid() const
+ bool header_is_valid() const
{
return ((common_header_len >= ((binlog_version==1) ? OLD_HEADER_LEN :
LOG_EVENT_MINIMAL_HEADER_LEN)) &&
(post_header_len != NULL));
}
+
+ bool version_is_valid() const
+ {
+ /* It is invalid only when all version numbers are 0 */
+ return !(server_version_split[0] == 0 &&
+ server_version_split[1] == 0 &&
+ server_version_split[2] == 0);
+ }
+
+ bool is_valid() const
+ {
+ return header_is_valid() && version_is_valid();
+ }
+
int get_data_size()
{
/*