1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-07 00:04:31 +03:00

MDEV-11319 mysqlbinlog crashes or fails with out of memory while reading some encrypted binlogs

support encrypted binlogs. Not decryption, but at least recognizing
that event are encrypted and prining them as such
This commit is contained in:
Sergei Golubchik
2016-12-03 20:34:50 +01:00
parent 952856c810
commit b5aa0f437f
5 changed files with 54 additions and 5 deletions

View File

@@ -1257,6 +1257,9 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
goto err;
break;
}
case START_ENCRYPTION_EVENT:
glob_description_event->start_decryption((Start_encryption_log_event*)ev);
/* fall through */
default:
print_skip_replication_statement(print_event_info, ev);
ev->print(result_file, print_event_info);
@@ -2837,9 +2840,16 @@ void *sql_alloc(size_t size)
return alloc_root(&s_mem_root, size);
}
uint dummy1() { return 1; }
struct encryption_service_st encryption_handler=
{
0, 0, 0, 0, 0, 0, 0
(uint(*)(uint))dummy1,
(uint(*)(uint, uint, uchar*, uint*))dummy1,
(uint(*)(uint, uint))dummy1,
(int (*)(void*, const uchar*, uint, const uchar*, uint, int, uint, uint))dummy1,
(int (*)(void*, const uchar*, uint, uchar*, uint*))dummy1,
(int (*)(void*, uchar*, uint*))dummy1,
(uint (*)(uint, uint, uint))dummy1
};
/*

View File

@@ -0,0 +1,6 @@
RESET MASTER;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2),(3);
REPLACE INTO t1 VALUES (4);
DROP TABLE t1;
FLUSH LOGS;

View File

@@ -0,0 +1,21 @@
source include/have_log_bin.inc;
source include/have_debug.inc;
let datadir=`select @@datadir`;
RESET MASTER;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2),(3);
REPLACE INTO t1 VALUES (4);
DROP TABLE t1;
FLUSH LOGS;
let filename= master-bin.000001;
let local=$datadir/$filename;
let remote=--read-from-remote-server --protocol=tcp --host=127.0.0.1 --port=$MASTER_MYPORT -uroot $filename;
let outfile=$MYSQLTEST_VARDIR/tmp/binlog_enc.sql;
--error 1
exec $MYSQL_BINLOG $local > $outfile;
exec $MYSQL_BINLOG $local --force-read >> $outfile;
exec $MYSQL_BINLOG $remote >> $outfile;
remove_file $outfile;

View File

@@ -1514,6 +1514,10 @@ err:
if (error)
{
DBUG_ASSERT(!res);
#ifdef MYSQL_CLIENT
if (force_opt)
DBUG_RETURN(new Unknown_log_event());
#endif
if (event.length() >= OLD_HEADER_LEN)
sql_print_error("Error in Log_event::read_log_event(): '%s',"
" data_len: %lu, event_type: %d", error,
@@ -8182,8 +8186,13 @@ void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info
if (print_event_info->short_form)
return;
if (what != ENCRYPTED)
{
print_header(&cache, print_event_info, FALSE);
my_b_printf(&cache, "\n# %s", "Unknown event\n");
my_b_printf(&cache, "\n# Unknown event\n");
}
else
my_b_printf(&cache, "# Encrypted event\n");
}
#endif

View File

@@ -1149,7 +1149,7 @@ public:
return thd ? thd->db : 0;
}
#else
Log_event() : temp_buf(0), flags(0) {}
Log_event() : temp_buf(0), when(0), flags(0) {}
ha_checksum crc;
/* print*() functions are used by mysqlbinlog */
virtual void print(FILE* file, PRINT_EVENT_INFO* print_event_info) = 0;
@@ -3677,6 +3677,7 @@ private:
class Unknown_log_event: public Log_event
{
public:
enum { UNKNOWN, ENCRYPTED } what;
/*
Even if this is an unknown event, we still pass description_event to
Log_event's ctor, this way we can extract maximum information from the
@@ -3684,8 +3685,10 @@ public:
*/
Unknown_log_event(const char* buf,
const Format_description_log_event *description_event):
Log_event(buf, description_event)
Log_event(buf, description_event), what(UNKNOWN)
{}
/* constructor for hopelessly corrupted events */
Unknown_log_event(): Log_event(), what(ENCRYPTED) {}
~Unknown_log_event() {}
void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
Log_event_type get_type_code() { return UNKNOWN_EVENT;}