Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
4032fc1d
Commit
4032fc1d
authored
Jan 08, 2020
by
Sujatha
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '10.3' into 10.4
parents
d2697dfb
b365b6e7
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
208 additions
and
31 deletions
+208
-31
mysql-test/suite/binlog/r/binlog_invalid_read_in_rotate.result
...-test/suite/binlog/r/binlog_invalid_read_in_rotate.result
+18
-0
mysql-test/suite/binlog/r/binlog_show_binlog_event_random_pos.result
...suite/binlog/r/binlog_show_binlog_event_random_pos.result
+12
-0
mysql-test/suite/binlog/t/binlog_invalid_read_in_rotate.combinations
...suite/binlog/t/binlog_invalid_read_in_rotate.combinations
+5
-0
mysql-test/suite/binlog/t/binlog_invalid_read_in_rotate.test
mysql-test/suite/binlog/t/binlog_invalid_read_in_rotate.test
+48
-0
mysql-test/suite/binlog/t/binlog_show_binlog_event_random_pos.combinations
...binlog/t/binlog_show_binlog_event_random_pos.combinations
+5
-0
mysql-test/suite/binlog/t/binlog_show_binlog_event_random_pos.test
...t/suite/binlog/t/binlog_show_binlog_event_random_pos.test
+37
-0
sql/log_event.cc
sql/log_event.cc
+66
-25
sql/sql_repl.cc
sql/sql_repl.cc
+17
-6
No files found.
mysql-test/suite/binlog/r/binlog_invalid_read_in_rotate.result
0 → 100644
View file @
4032fc1d
RESET MASTER;
call mtr.add_suppression("Error in Log_event::read_log_event*");
call mtr.add_suppression("Replication event checksum verification failed while reading from a log file*");
DROP TABLE /*! IF EXISTS*/ t1;
Warnings:
Note 1051 Unknown table 'test.t1'
CREATE TABLE `t1` (
`col_int` int,
pk integer auto_increment,
`col_char_12_key` char(12),
`col_int_key` int,
`col_char_12` char(12),
primary key (pk),
key (`col_char_12_key` ),
key (`col_int_key` )) ENGINE=InnoDB;
INSERT /*! IGNORE */ INTO t1 VALUES (183173120, NULL, 'abcd', 1, 'efghijk'), (1, NULL, 'lmno', 2, 'p');
ALTER TABLE `t1` ENABLE KEYS;
DROP TABLE t1;
mysql-test/suite/binlog/r/binlog_show_binlog_event_random_pos.result
0 → 100644
View file @
4032fc1d
RESET MASTER;
call mtr.add_suppression("Error in Log_event::read_log_event*");
call mtr.add_suppression("Replication event checksum verification failed while reading from a log file*");
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 'test.t1'
CREATE TABLE t1 (c1 CHAR(255), c2 CHAR(255), c3 CHAR(255), c4 CHAR(255), c5 CHAR(255));
INSERT INTO t1 VALUES (repeat('a', 255), repeat('a', 255),repeat('a', 255),repeat('a', 255),repeat('a', 255));
INSERT INTO t1 VALUES (repeat('a', 255), repeat('a', 255),repeat('a', 255),repeat('a', 255),repeat('a', 255));
UPDATE t1 SET c1=repeat('b',255);
INSERT INTO t1 VALUES (repeat('a', 255), repeat('a', 255),repeat('a', 255),repeat('a', 255),repeat('a', 255));
DROP TABLE t1;
mysql-test/suite/binlog/t/binlog_invalid_read_in_rotate.combinations
0 → 100644
View file @
4032fc1d
[enable_checksum]
binlog_checksum=1
[disable_checksum]
binlog_checksum=0
mysql-test/suite/binlog/t/binlog_invalid_read_in_rotate.test
0 → 100644
View file @
4032fc1d
# ==== Purpose ====
#
# Test verifies that reading binary log by using "SHOW BINLOG EVENTS" command
# from various random positions doesn't lead to crash. It should exit
# gracefully with appropriate error.
#
# ==== References ====
#
# MDEV-18046:Assortment of crashes, assertion failures and ASAN errors in mysql_show_binlog_events
--
source
include
/
have_log_bin
.
inc
--
source
include
/
have_innodb
.
inc
RESET
MASTER
;
call
mtr
.
add_suppression
(
"Error in Log_event::read_log_event*"
);
call
mtr
.
add_suppression
(
"Replication event checksum verification failed while reading from a log file*"
);
DROP
TABLE
/*! IF EXISTS*/
t1
;
CREATE
TABLE
`t1`
(
`col_int`
int
,
pk
integer
auto_increment
,
`col_char_12_key`
char
(
12
),
`col_int_key`
int
,
`col_char_12`
char
(
12
),
primary
key
(
pk
),
key
(
`col_char_12_key`
),
key
(
`col_int_key`
))
ENGINE
=
InnoDB
;
INSERT
/*! IGNORE */
INTO
t1
VALUES
(
183173120
,
NULL
,
'abcd'
,
1
,
'efghijk'
),
(
1
,
NULL
,
'lmno'
,
2
,
'p'
);
--
disable_warnings
ALTER
TABLE
`t1`
ENABLE
KEYS
;
--
enable_warnings
--
let
$max_pos
=
query_get_value
(
SHOW
MASTER
STATUS
,
Position
,
1
)
--
let
$pos
=
1
while
(
$pos
<=
$max_pos
)
{
--
disable_query_log
--
disable_result_log
--
error
0
,
1220
eval
SHOW
BINLOG
EVENTS
FROM
$pos
;
--
inc
$pos
--
enable_result_log
--
enable_query_log
}
DROP
TABLE
t1
;
mysql-test/suite/binlog/t/binlog_show_binlog_event_random_pos.combinations
0 → 100644
View file @
4032fc1d
[enable_checksum]
binlog_checksum=1
[disable_checksum]
binlog_checksum=0
mysql-test/suite/binlog/t/binlog_show_binlog_event_random_pos.test
0 → 100644
View file @
4032fc1d
# ==== Purpose ====
#
# Test verifies that reading binary log by using "SHOW BINLOG EVENTS" command
# from various random positions doesn't lead to crash. It should exit
# gracefully with appropriate error.
#
# ==== References ====
#
# MDEV-18046:Assortment of crashes, assertion failures and ASAN errors in mysql_show_binlog_events
--
source
include
/
have_log_bin
.
inc
--
source
include
/
have_innodb
.
inc
RESET
MASTER
;
call
mtr
.
add_suppression
(
"Error in Log_event::read_log_event*"
);
call
mtr
.
add_suppression
(
"Replication event checksum verification failed while reading from a log file*"
);
DROP
TABLE
IF
EXISTS
t1
;
CREATE
TABLE
t1
(
c1
CHAR
(
255
),
c2
CHAR
(
255
),
c3
CHAR
(
255
),
c4
CHAR
(
255
),
c5
CHAR
(
255
));
INSERT
INTO
t1
VALUES
(
repeat
(
'a'
,
255
),
repeat
(
'a'
,
255
),
repeat
(
'a'
,
255
),
repeat
(
'a'
,
255
),
repeat
(
'a'
,
255
));
INSERT
INTO
t1
VALUES
(
repeat
(
'a'
,
255
),
repeat
(
'a'
,
255
),
repeat
(
'a'
,
255
),
repeat
(
'a'
,
255
),
repeat
(
'a'
,
255
));
UPDATE
t1
SET
c1
=
repeat
(
'b'
,
255
);
INSERT
INTO
t1
VALUES
(
repeat
(
'a'
,
255
),
repeat
(
'a'
,
255
),
repeat
(
'a'
,
255
),
repeat
(
'a'
,
255
),
repeat
(
'a'
,
255
));
--
let
$max_pos
=
query_get_value
(
SHOW
MASTER
STATUS
,
Position
,
1
)
--
let
$pos
=
1
while
(
$pos
<=
$max_pos
)
{
--
disable_query_log
--
disable_result_log
--
error
0
,
1220
eval
SHOW
BINLOG
EVENTS
FROM
$pos
LIMIT
100
;
--
inc
$pos
--
enable_result_log
--
enable_query_log
}
DROP
TABLE
t1
;
sql/log_event.cc
View file @
4032fc1d
...
...
@@ -1052,9 +1052,14 @@ row_log_event_uncompress(const Format_description_log_event *description_event,
uint32
binlog_get_uncompress_len
(
const
char
*
buf
)
{
DBUG_ASSERT
((
buf
[
0
]
&
0xe0
)
==
0x80
);
uint32
lenlen
=
buf
[
0
]
&
0x07
;
uint32
len
=
0
;
uint32
lenlen
=
0
;
if
((
buf
==
NULL
)
||
((
buf
[
0
]
&
0xe0
)
!=
0x80
))
return
len
;
lenlen
=
buf
[
0
]
&
0x07
;
switch
(
lenlen
)
{
case
1
:
...
...
@@ -4578,6 +4583,17 @@ code_name(int code)
}
#endif
#define VALIDATE_BYTES_READ(CUR_POS, START, EVENT_LEN) \
do { \
uchar *cur_pos= (uchar *)CUR_POS; \
uchar *start= (uchar *)START; \
uint len= EVENT_LEN; \
uint bytes_read= (uint)(cur_pos - start); \
DBUG_PRINT("info", ("Bytes read: %u event_len:%u.\n",\
bytes_read, len)); \
if (bytes_read >= len) \
DBUG_VOID_RETURN; \
} while (0)
/**
Macro to check that there is enough space to read from memory.
...
...
@@ -4589,7 +4605,6 @@ code_name(int code)
#define CHECK_SPACE(PTR,END,CNT) \
do { \
DBUG_PRINT("info", ("Read %s", code_name(pos[-1]))); \
DBUG_ASSERT((PTR) + (CNT) <= (END)); \
if ((PTR) + (CNT) > (END)) { \
DBUG_PRINT("info", ("query= 0")); \
query= 0; \
...
...
@@ -4924,7 +4939,9 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
uint32
max_length
=
uint32
(
event_len
-
((
const
char
*
)(
end
+
db_len
+
1
)
-
(
buf
-
common_header_len
)));
if
(
q_len
!=
max_length
)
if
(
q_len
!=
max_length
||
(
event_len
<
uint
((
const
char
*
)(
end
+
db_len
+
1
)
-
(
buf
-
common_header_len
))))
{
q_len
=
0
;
query
=
NULL
;
...
...
@@ -7110,6 +7127,8 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
{
DBUG_ENTER
(
"Load_log_event::copy_log_event"
);
uint
data_len
;
if
((
int
)
event_len
<
body_offset
)
DBUG_RETURN
(
1
);
char
*
buf_end
=
(
char
*
)
buf
+
event_len
;
/* this is the beginning of the post-header */
const
char
*
data_head
=
buf
+
description_event
->
common_header_len
;
...
...
@@ -7119,9 +7138,7 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
table_name_len
=
(
uint
)
data_head
[
L_TBL_LEN_OFFSET
];
db_len
=
(
uint
)
data_head
[
L_DB_LEN_OFFSET
];
num_fields
=
uint4korr
(
data_head
+
L_NUM_FIELDS_OFFSET
);
if
((
int
)
event_len
<
body_offset
)
DBUG_RETURN
(
1
);
/*
Sql_ex.init() on success returns the pointer to the first byte after
the sql_ex structure, which is the start of field lengths array.
...
...
@@ -7130,7 +7147,7 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
buf_end
,
(
uchar
)
buf
[
EVENT_TYPE_OFFSET
]
!=
LOAD_EVENT
)))
DBUG_RETURN
(
1
);
data_len
=
event_len
-
body_offset
;
if
(
num_fields
>
data_len
)
// simple sanity check against corruption
DBUG_RETURN
(
1
);
...
...
@@ -7695,7 +7712,7 @@ Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
// The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
uint8
post_header_len
=
description_event
->
post_header_len
[
ROTATE_EVENT
-
1
];
uint
ident_offset
;
if
(
event_len
<
LOG_EVENT_MINIMAL_HEADER_LEN
)
if
(
event_len
<
(
uint
)(
LOG_EVENT_MINIMAL_HEADER_LEN
+
post_header_len
)
)
DBUG_VOID_RETURN
;
buf
+=
LOG_EVENT_MINIMAL_HEADER_LEN
;
pos
=
post_header_len
?
uint8korr
(
buf
+
R_POS_OFFSET
)
:
4
;
...
...
@@ -9268,6 +9285,11 @@ User_var_log_event(const char* buf, uint event_len,
we keep the flags set to UNDEF_F.
*/
size_t
bytes_read
=
(
val
+
val_len
)
-
buf_start
;
if
(
bytes_read
>
event_len
)
{
error
=
true
;
goto
err
;
}
if
((
data_written
-
bytes_read
)
>
0
)
{
flags
=
(
uint
)
*
(
buf
+
UV_VAL_IS_NULL
+
UV_VAL_TYPE_SIZE
+
...
...
@@ -10891,7 +10913,8 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
uint8
const
common_header_len
=
description_event
->
common_header_len
;
Log_event_type
event_type
=
(
Log_event_type
)(
uchar
)
buf
[
EVENT_TYPE_OFFSET
];
m_type
=
event_type
;
m_cols_ai
.
bitmap
=
0
;
uint8
const
post_header_len
=
description_event
->
post_header_len
[
event_type
-
1
];
DBUG_PRINT
(
"enter"
,(
"event_len: %u common_header_len: %d "
...
...
@@ -10925,7 +10948,14 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
which includes length bytes
*/
var_header_len
=
uint2korr
(
post_start
);
assert
(
var_header_len
>=
2
);
/* Check length and also avoid out of buffer read */
if
(
var_header_len
<
2
||
event_len
<
static_cast
<
unsigned
int
>
(
var_header_len
+
(
post_start
-
buf
)))
{
m_cols
.
bitmap
=
0
;
DBUG_VOID_RETURN
;
}
var_header_len
-=
2
;
/* Iterate over var-len header, extracting 'chunks' */
...
...
@@ -12597,14 +12627,12 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
m_data_size
(
0
),
m_field_metadata
(
0
),
m_field_metadata_size
(
0
),
m_null_bits
(
0
),
m_meta_memory
(
NULL
)
{
unsigned
int
bytes_read
=
0
;
DBUG_ENTER
(
"Table_map_log_event::Table_map_log_event(const char*,uint,...)"
);
uint8
common_header_len
=
description_event
->
common_header_len
;
uint8
post_header_len
=
description_event
->
post_header_len
[
TABLE_MAP_EVENT
-
1
];
DBUG_PRINT
(
"info"
,(
"event_len: %u common_header_len: %d post_header_len: %d"
,
event_len
,
common_header_len
,
post_header_len
));
/*
Don't print debug messages when running valgrind since they can
trigger false warnings.
...
...
@@ -12613,6 +12641,9 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
DBUG_DUMP
(
"event buffer"
,
(
uchar
*
)
buf
,
event_len
);
#endif
if
(
event_len
<
(
uint
)(
common_header_len
+
post_header_len
))
DBUG_VOID_RETURN
;
/* Read the post-header */
const
char
*
post_start
=
buf
+
common_header_len
;
...
...
@@ -12639,15 +12670,18 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
/* Extract the length of the various parts from the buffer */
uchar
const
*
const
ptr_dblen
=
(
uchar
const
*
)
vpart
+
0
;
VALIDATE_BYTES_READ
(
ptr_dblen
,
buf
,
event_len
);
m_dblen
=
*
(
uchar
*
)
ptr_dblen
;
/* Length of database name + counter + terminating null */
uchar
const
*
const
ptr_tbllen
=
ptr_dblen
+
m_dblen
+
2
;
VALIDATE_BYTES_READ
(
ptr_tbllen
,
buf
,
event_len
);
m_tbllen
=
*
(
uchar
*
)
ptr_tbllen
;
/* Length of table name + counter + terminating null */
uchar
const
*
const
ptr_colcnt
=
ptr_tbllen
+
m_tbllen
+
2
;
uchar
*
ptr_after_colcnt
=
(
uchar
*
)
ptr_colcnt
;
VALIDATE_BYTES_READ
(
ptr_after_colcnt
,
buf
,
event_len
);
m_colcnt
=
net_field_length
(
&
ptr_after_colcnt
);
DBUG_PRINT
(
"info"
,(
"m_dblen: %lu off: %ld m_tbllen: %lu off: %ld m_colcnt: %lu off: %ld"
,
...
...
@@ -12670,23 +12704,27 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
memcpy
(
m_coltype
,
ptr_after_colcnt
,
m_colcnt
);
ptr_after_colcnt
=
ptr_after_colcnt
+
m_colcnt
;
bytes_read
=
(
uint
)
(
ptr_after_colcnt
-
(
uchar
*
)
buf
);
DBUG_PRINT
(
"info"
,
(
"Bytes read: %d"
,
bytes_read
)
);
if
(
bytes_read
<
event_len
)
VALIDATE_BYTES_READ
(
ptr_after_colcnt
,
buf
,
event_len
);
m_field_metadata_size
=
net_field_length
(
&
ptr_after_colcnt
);
if
(
m_field_metadata_size
<=
(
m_colcnt
*
2
)
)
{
m_field_metadata_size
=
net_field_length
(
&
ptr_after_colcnt
);
DBUG_ASSERT
(
m_field_metadata_size
<=
(
m_colcnt
*
2
));
uint
num_null_bytes
=
(
m_colcnt
+
7
)
/
8
;
m_meta_memory
=
(
uchar
*
)
my_multi_malloc
(
MYF
(
MY_WME
),
&
m_null_bits
,
num_null_bytes
,
&
m_field_metadata
,
m_field_metadata_size
,
NULL
);
&
m_null_bits
,
num_null_bytes
,
&
m_field_metadata
,
m_field_metadata_size
,
NULL
);
memcpy
(
m_field_metadata
,
ptr_after_colcnt
,
m_field_metadata_size
);
ptr_after_colcnt
=
(
uchar
*
)
ptr_after_colcnt
+
m_field_metadata_size
;
memcpy
(
m_null_bits
,
ptr_after_colcnt
,
num_null_bytes
);
}
else
{
m_coltype
=
NULL
;
my_free
(
m_memory
);
m_memory
=
NULL
;
DBUG_VOID_RETURN
;
}
}
DBUG_VOID_RETURN
;
}
#endif
...
...
@@ -14541,9 +14579,12 @@ void Update_rows_log_event::init(MY_BITMAP const *cols)
Update_rows_log_event
::~
Update_rows_log_event
()
{
if
(
m_cols_ai
.
bitmap
==
m_bitbuf_ai
)
// no my_malloc happened
m_cols_ai
.
bitmap
=
0
;
// so no my_free in my_bitmap_free
my_bitmap_free
(
&
m_cols_ai
);
// To pair with my_bitmap_init().
if
(
m_cols_ai
.
bitmap
)
{
if
(
m_cols_ai
.
bitmap
==
m_bitbuf_ai
)
// no my_malloc happened
m_cols_ai
.
bitmap
=
0
;
// so no my_free in my_bitmap_free
my_bitmap_free
(
&
m_cols_ai
);
// To pair with my_bitmap_init().
}
}
...
...
sql/sql_repl.cc
View file @
4032fc1d
...
...
@@ -3975,6 +3975,11 @@ bool mysql_show_binlog_events(THD* thd)
List
<
Item
>
field_list
;
const
char
*
errmsg
=
0
;
bool
ret
=
TRUE
;
/*
Using checksum validate the correctness of event pos specified in show
binlog events command.
*/
bool
verify_checksum_once
=
false
;
IO_CACHE
log
;
File
file
=
-
1
;
MYSQL_BIN_LOG
*
binary_log
=
NULL
;
...
...
@@ -4030,6 +4035,10 @@ bool mysql_show_binlog_events(THD* thd)
mi
=
0
;
}
/* Validate user given position using checksum */
if
(
lex_mi
->
pos
==
pos
&&
!
opt_master_verify_checksum
)
verify_checksum_once
=
true
;
unit
->
set_limit
(
thd
->
lex
->
current_select
);
limit_start
=
unit
->
offset_limit_cnt
;
limit_end
=
unit
->
select_limit_cnt
;
...
...
@@ -4109,15 +4118,16 @@ bool mysql_show_binlog_events(THD* thd)
for
(
event_count
=
0
;
(
ev
=
Log_event
::
read_log_event
(
&
log
,
description_event
,
opt_master_verify_checksum
));
)
(
opt_master_verify_checksum
||
verify_checksum_once
)));
)
{
if
(
event_count
>=
limit_start
&&
ev
->
net_send
(
protocol
,
linfo
.
log_file_name
,
pos
))
ev
->
net_send
(
protocol
,
linfo
.
log_file_name
,
pos
))
{
errmsg
=
"Net error"
;
delete
ev
;
errmsg
=
"Net error"
;
delete
ev
;
mysql_mutex_unlock
(
log_lock
);
goto
err
;
goto
err
;
}
if
(
ev
->
get_type_code
()
==
FORMAT_DESCRIPTION_EVENT
)
...
...
@@ -4143,10 +4153,11 @@ bool mysql_show_binlog_events(THD* thd)
delete
ev
;
}
verify_checksum_once
=
false
;
pos
=
my_b_tell
(
&
log
);
if
(
++
event_count
>=
limit_end
)
break
;
break
;
}
if
(
unlikely
(
event_count
<
limit_end
&&
log
.
error
))
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment