Commit b5aa0f43 authored by Sergei Golubchik's avatar Sergei Golubchik

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
parent 952856c8
......@@ -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
};
/*
......
RESET MASTER;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2),(3);
REPLACE INTO t1 VALUES (4);
DROP TABLE t1;
FLUSH LOGS;
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;
......@@ -1514,6 +1514,10 @@ Log_event* Log_event::read_log_event(IO_CACHE* file, mysql_mutex_t* log_lock,
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;
print_header(&cache, print_event_info, FALSE);
my_b_printf(&cache, "\n# %s", "Unknown event\n");
if (what != ENCRYPTED)
{
print_header(&cache, print_event_info, FALSE);
my_b_printf(&cache, "\n# Unknown event\n");
}
else
my_b_printf(&cache, "# Encrypted event\n");
}
#endif
......
......@@ -1149,7 +1149,7 @@ class Log_event
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 @@ class Execute_load_query_log_event: public Query_log_event
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 @@ class Unknown_log_event: public Log_event
*/
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;}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment