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.
This commit is contained in:
parent
672a6496e0
commit
e7e9fa599a
@ -4205,7 +4205,6 @@ Format_description_log_event::do_shall_skip(Relay_log_info *rli)
|
|||||||
into 'server_version_split':
|
into 'server_version_split':
|
||||||
X.Y.Zabc (X,Y,Z numbers, a not a digit) -> {X,Y,Z}
|
X.Y.Zabc (X,Y,Z numbers, a not a digit) -> {X,Y,Z}
|
||||||
X.Yabc -> {X,Y,0}
|
X.Yabc -> {X,Y,0}
|
||||||
Xabc -> {X,0,0}
|
|
||||||
'server_version_split' is then used for lookups to find if the server which
|
'server_version_split' is then used for lookups to find if the server which
|
||||||
created this event has some known bug.
|
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++)
|
for (uint i= 0; i<=2; i++)
|
||||||
{
|
{
|
||||||
number= strtoul(p, &r, 10);
|
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;
|
p= r;
|
||||||
DBUG_ASSERT(!((i == 0) && (*r != '.'))); // should be true in practice
|
|
||||||
if (*r == '.')
|
if (*r == '.')
|
||||||
p++; // skip the dot
|
p++; // skip the dot
|
||||||
}
|
}
|
||||||
|
@ -969,7 +969,7 @@ public:
|
|||||||
return thd ? thd->db : 0;
|
return thd ? thd->db : 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
Log_event() : temp_buf(0) {}
|
Log_event() : temp_buf(0), flags(0) {}
|
||||||
/* avoid having to link mysqlbinlog against libpthread */
|
/* avoid having to link mysqlbinlog against libpthread */
|
||||||
static Log_event* read_log_event(IO_CACHE* file,
|
static Log_event* read_log_event(IO_CACHE* file,
|
||||||
const Format_description_log_event
|
const Format_description_log_event
|
||||||
@ -2244,12 +2244,26 @@ public:
|
|||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
bool write(IO_CACHE* file);
|
bool write(IO_CACHE* file);
|
||||||
#endif
|
#endif
|
||||||
bool is_valid() const
|
bool header_is_valid() const
|
||||||
{
|
{
|
||||||
return ((common_header_len >= ((binlog_version==1) ? OLD_HEADER_LEN :
|
return ((common_header_len >= ((binlog_version==1) ? OLD_HEADER_LEN :
|
||||||
LOG_EVENT_MINIMAL_HEADER_LEN)) &&
|
LOG_EVENT_MINIMAL_HEADER_LEN)) &&
|
||||||
(post_header_len != NULL));
|
(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()
|
int get_data_size()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user