summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSven Sandberg <sven@mysql.com>2008-12-29 17:04:10 +0100
committerSven Sandberg <sven@mysql.com>2008-12-29 17:04:10 +0100
commitba835f89ba4a07344322765c27c424a2ea96f6ee (patch)
tree140102f9249f7ff4d6beb0772df2511a8ec0abc8 /sql
parent47c0ec508467b4941e6e388e33dc688b7247befb (diff)
downloadmariadb-git-ba835f89ba4a07344322765c27c424a2ea96f6ee.tar.gz
BUG#40482: server/mysqlbinlog crashes when reading invalid Incident_log_event
Problem: When an Incident_log_event contains a bad incident number on disk, the server crashes with an assertion. Fix: Don't validate input with assertions. Use errors. mysql-test/include/cleanup_fake_relay_log.inc: Added auxiliary file to restore things that setup_fake_relay_log.inc did. mysql-test/include/setup_fake_relay_log.inc: Added auxiliary file to setup replication from an existing relay log. mysql-test/std_data/bug40482-bin.000001: Binlog file for rpl.rpl_binlog_corruption mysql-test/suite/rpl/t/rpl_binlog_corruption.test: New test file. sql/log_event.cc: Check that the incident number is correct at the time the event is constructed. Do not assert it at the time it is printed. sql/log_event.h: Incident_log_event::is_valid() should verify that the incident number is valid. sql/rpl_constants.h: Incident numbers should be hard-coded, since they may appear in files.
Diffstat (limited to 'sql')
-rw-r--r--sql/log_event.cc15
-rw-r--r--sql/log_event.h5
-rw-r--r--sql/rpl_constants.h4
3 files changed, 17 insertions, 7 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc
index cd8fa0c3a85..74ad018df55 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -9057,7 +9057,17 @@ Incident_log_event::Incident_log_event(const char *buf, uint event_len,
DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
event_len, common_header_len, post_header_len));
- m_incident= static_cast<Incident>(uint2korr(buf + common_header_len));
+ int incident_number= uint2korr(buf + common_header_len);
+ if (incident_number >= INCIDENT_COUNT ||
+ incident_number <= INCIDENT_NONE)
+ {
+ // If the incident is not recognized, this binlog event is
+ // invalid. If we set incident_number to INCIDENT_NONE, the
+ // invalidity will be detected by is_valid().
+ incident_number= INCIDENT_NONE;
+ DBUG_VOID_RETURN;
+ }
+ m_incident= static_cast<Incident>(incident_number);
char const *ptr= buf + common_header_len + post_header_len;
char const *const str_end= buf + event_len;
uint8 len= 0; // Assignment to keep compiler happy
@@ -9085,9 +9095,6 @@ Incident_log_event::description() const
DBUG_PRINT("info", ("m_incident: %d", m_incident));
- DBUG_ASSERT(0 <= m_incident);
- DBUG_ASSERT((size_t) m_incident <= sizeof(description)/sizeof(*description));
-
return description[m_incident];
}
diff --git a/sql/log_event.h b/sql/log_event.h
index 3c109b798d3..db14341b51d 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -3870,7 +3870,10 @@ public:
virtual Log_event_type get_type_code() { return INCIDENT_EVENT; }
- virtual bool is_valid() const { return 1; }
+ virtual bool is_valid() const
+ {
+ return m_incident > INCIDENT_NONE && m_incident < INCIDENT_COUNT;
+ }
virtual int get_data_size() {
return INCIDENT_HEADER_LEN + 1 + m_message.length;
}
diff --git a/sql/rpl_constants.h b/sql/rpl_constants.h
index 426e80a328d..32fb4b8a7f2 100644
--- a/sql/rpl_constants.h
+++ b/sql/rpl_constants.h
@@ -6,10 +6,10 @@
*/
enum Incident {
/** No incident */
- INCIDENT_NONE,
+ INCIDENT_NONE = 0,
/** There are possibly lost events in the replication stream */
- INCIDENT_LOST_EVENTS,
+ INCIDENT_LOST_EVENTS = 1,
/** Shall be last event of the enumeration */
INCIDENT_COUNT