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.
parent 94f0977b
...@@ -632,6 +632,9 @@ bool ha_myisam::check_if_locking_is_allowed(uint sql_command, ...@@ -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) int ha_myisam::open(const char *name, int mode, uint test_if_locked)
{ {
MI_KEYDEF *keyinfo;
MI_COLUMNDEF *recinfo= 0;
uint recs;
uint i; uint i;
/* /*
...@@ -654,6 +657,26 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked) ...@@ -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))) if (!(file=mi_open(name, mode, test_if_locked | HA_OPEN_FROM_SQL_LAYER)))
return (my_errno ? my_errno : -1); 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)) if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
VOID(mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0)); 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) ...@@ -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; table->key_info[i].block_size= file->s->keyinfo[i].block_length;
} }
return (0); 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) int ha_myisam::close(void)
......
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