Commit a5c27d6c authored by unknown's avatar unknown
Browse files

BUG#25908 - corrupted myisam table crashes server even after repair

Opening certain tables that have different definitions in .MYI and
.frm may result in a server crash.

Compare .MYI and .frm definition when myisam table is opened. In case
definitions are diffirent refuse to open such table.

No test case, since it requires broken table.


storage/myisam/ha_myisam.cc:
  Compare .MYI and .frm definition when myisam table is opened. In case
  definitions are diffirent refuse to open such table.
parent 8deff6b0
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -632,6 +632,9 @@ bool ha_myisam::check_if_locking_is_allowed(uint sql_command,

int ha_myisam::open(const char *name, int mode, uint test_if_locked)
{
  MI_KEYDEF *keyinfo;
  MI_COLUMNDEF *recinfo= 0;
  uint recs;
  uint i;

  /*
@@ -654,6 +657,26 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)

  if (!(file=mi_open(name, mode, test_if_locked | HA_OPEN_FROM_SQL_LAYER)))
    return (my_errno ? my_errno : -1);
  if (!table->s->tmp_table) /* No need to perform a check for tmp table */
  {
    if ((my_errno= table2myisam(table, &keyinfo, &recinfo, &recs)))
    {
      /* purecov: begin inspected */
      DBUG_PRINT("error", ("Failed to convert TABLE object to MyISAM "
                           "key and column definition"));
      goto err;
      /* purecov: end */
    }
    if (check_definition(keyinfo, recinfo, table->s->keys, recs,
                         file->s->keyinfo, file->s->rec,
                         file->s->base.keys, file->s->base.fields, true))
    {
      /* purecov: begin inspected */
      my_errno= HA_ERR_CRASHED;
      goto err;
      /* purecov: end */
    }
  }
  
  if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
    VOID(mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
@@ -675,6 +698,15 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
    table->key_info[i].block_size= file->s->keyinfo[i].block_length;
  }
  return (0);
err:
  this->close();
  /*
    Both recinfo and keydef are allocated by my_multi_malloc(), thus only
    recinfo must be freed.
  */
  if (recinfo)
    my_free((gptr) recinfo, MYF(0));
  return my_errno;
}

int ha_myisam::close(void)