Bug #40482 server/mysqlbinlog crashes when reading invalid Incident_log_event
Submitted: 3 Nov 2008 16:45 Modified: 20 Jan 2009 21:57
Reporter: Sven Sandberg Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Replication Severity:S2 (Serious)
Version:5.1+ OS:Any
Assigned to: Sven Sandberg CPU Architecture:Any
Tags: crash, Incident_log_event, replication

[3 Nov 2008 16:45] Sven Sandberg
Description:
When the server reads a binlog with an Incident_log_event containing an invalid incident number, and debug mode is on, it raises an assertion.

Moreover, the assertion causes a compiler warning with this version of gcc:

"C++ compiler version"... "g++ g++ (GCC) 4.1.2 20071124 (Red Hat 4.1.2-42)"

on 64 bit Linux.

How to repeat:
source include/have_log_bin.inc;
source include/have_debug.inc;

exec $MYSQL_BINLOG < $MYSQL_TEST_DIR/std_data/bug-bin.000001;

I'll upload bug-bin.000001 shortly.

Suggested fix:
Don't use assertions to validate input, use errors:

=== modified file 'sql/log_event.cc'
--- sql/log_event.cc	2008-10-23 19:27:09 +0000
+++ sql/log_event.cc	2008-11-03 16:11:06 +0000
@@ -9035,7 +9035,17 @@ Incident_log_event::Incident_log_event(c
   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 >= (int)INCIDENT_COUNT ||
+      incident_number <= (int)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
@@ -9063,9 +9073,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];
 }
 

=== modified file 'sql/log_event.h'
--- sql/log_event.h	2008-09-29 05:36:42 +0000
+++ sql/log_event.h	2008-11-03 16:11:22 +0000
@@ -3886,7 +3886,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 (int)m_incident > INCIDENT_NONE && (int)m_incident < INCIDENT_COUNT;
+  }
   virtual int get_data_size() {
     return INCIDENT_HEADER_LEN + 1 + m_message.length;
   }

=== modified file 'sql/rpl_constants.h'
--- sql/rpl_constants.h	2007-03-29 18:31:09 +0000
+++ sql/rpl_constants.h	2008-11-03 16:05:08 +0000
@@ -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
[3 Nov 2008 16:47] Sven Sandberg
binlog containing a bad Incident_log_event (created with a hex editor)

Attachment: bug-bin.000001 (application/octet-stream, text), 172 bytes.

[3 Nov 2008 20:30] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/57728

2689 Sven Sandberg	2008-11-03
      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.
[6 Nov 2008 13:59] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/58015

2692 Sven Sandberg	2008-11-06
      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.
[10 Nov 2008 10:00] Øystein Grøvlen
Patch approved.
[13 Nov 2008 11:58] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/58621

2693 Sven Sandberg	2008-11-13
      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.
[13 Nov 2008 12:06] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/58623

2725 Sven Sandberg	2008-11-13 [merge]
      merge fix of BUG#40482 from 5.1-rpl to 6.0-rpl
[13 Nov 2008 17:46] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/58686

2706 Sven Sandberg	2008-11-13
      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.
[14 Nov 2008 13:23] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/58780

2724 Jorgen Loland	2008-11-14
      Bug#40482
      
      Assert gives compile warning - allways true. Removed assert for now.
[14 Nov 2008 14:50] Bugs System
Pushed into 6.0.9-alpha  (revid:jorgen.loland@sun.com-20081114132432-fgiaoshyse5y6db5) (version source revid:jorgen.loland@sun.com-20081114134411-xypyf8wyjc2nm3ly) (pib:5)
[29 Dec 2008 16:02] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/62420

2756 Sven Sandberg	2008-12-29
      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.
[30 Dec 2008 8:49] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/62433

2830 Sven Sandberg	2008-12-30 [merge]
      merged BUG#40482 from 5.1-bugteam to 6.0-bugteam.
[30 Dec 2008 8:51] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/62434

2830 Sven Sandberg	2008-12-30 [merge]
      merged BUG#40482 from 5.1-bugteam to 6.0-bugteam.
[30 Dec 2008 8:59] Sven Sandberg
Pushed to 5.1-bugteam and 6.0-bugteam.

Note: the test case uses the warning suppression mechanism of the new mtr, which only exists in 5.1-rpl and 6.0-rpl. That causes the test to fail in all non-mtr trees. Hence, I disabled the test case. Please re-enable it in 5.1-rpl and 6.0-rpl. See also BUG#41793.
[15 Jan 2009 6:38] Bugs System
Pushed into 5.1.31 (revid:joro@sun.com-20090115053147-tx1oapthnzgvs1ro) (version source revid:azundris@mysql.com-20081230115100-yqf6sa5zm553bqtr) (merge vers: 5.1.31) (pib:6)
[16 Jan 2009 19:57] Jon Stephens
Documented in the 5.1.31 changelog as follows:

        Attempting to read a binary log containing an Incident_log_event
        having an invalid incident number could cause the debug server
        to crash.

Set status to NDI pending merge to 6.0.
[19 Jan 2009 11:32] Bugs System
Pushed into 5.1.31-ndb-6.2.17 (revid:tomas.ulin@sun.com-20090119095303-uwwvxiibtr38djii) (version source revid:tomas.ulin@sun.com-20090115073240-1wanl85vlvw2she1) (merge vers: 5.1.31-ndb-6.2.17) (pib:6)
[19 Jan 2009 13:09] Bugs System
Pushed into 5.1.31-ndb-6.3.21 (revid:tomas.ulin@sun.com-20090119104956-guxz190n2kh31fxl) (version source revid:tomas.ulin@sun.com-20090119104956-guxz190n2kh31fxl) (merge vers: 5.1.31-ndb-6.3.21) (pib:6)
[19 Jan 2009 14:02] Jon Stephens
Set status back to NDI pending merge to 6.0 tree.
[19 Jan 2009 16:14] Bugs System
Pushed into 5.1.31-ndb-6.4.1 (revid:tomas.ulin@sun.com-20090119144033-4aylstx5czzz88i5) (version source revid:tomas.ulin@sun.com-20090119144033-4aylstx5czzz88i5) (merge vers: 5.1.31-ndb-6.4.1) (pib:6)
[19 Jan 2009 17:07] Jon Stephens
Set back to NDI pending merge to 6.0.
[20 Jan 2009 19:00] Bugs System
Pushed into 6.0.10-alpha (revid:joro@sun.com-20090119171328-2hemf2ndc1dxl0et) (version source revid:azundris@mysql.com-20081230114916-c290n83z25wkt6e4) (merge vers: 6.0.9-alpha) (pib:6)
[20 Jan 2009 21:57] Jon Stephens
Fix also documented in the 6.0.10 changelog; closed.