Commit 9d0c1ce5 authored by Sergey Vojtovich's avatar Sergey Vojtovich

BUG#48438 - crash with error in unioned query against merge

            table and view...

Invalid memory reads after a query referencing MyISAM table
multiple times with write lock. Invalid memory reads may
lead to server crash, valgrind warnings, incorrect values
in INFORMATION_SCHEMA.TABLES.{TABLE_ROWS, DATA_LENGTH,
INDEX_LENGTH, ...}.

This may happen when one of the table instances gets closed
after a query, e.g. out of slots in open tables cache. UNION,
MERGE and VIEW are irrelevant.

The problem was that MyISAM didn't restore state info
pointer to default value.

myisam/mi_locking.c:
  When a query is referencing MyISAM table multiple times
  with a write lock, all table instances share the same
  state info, pointing to MI_INFO::save_state of
  "primary" table instance.
  
  When lock is released, state pointer was restored only
  for the primary table instance. Secondary table instances
  are still pointing to save_state of primary table
  instance.
  
  Primary table instance may get closed, leaving secondary
  table instances state pointer pointing to freed memory.
  
  That's mostly ok, since next lock will update state info
  pointer to correct value. But there're some cases, when
  this secondary table instance state info is accessed
  without a lock, e.g. INFORMATION_SCHEMA, MERGE (in 5.1
  and up), MyISAM itself for DBUG purposes.
  
  Restore default value of state pointer unconditionally,
  for both primary and secondary table instances.
mysql-test/r/myisam.result:
  A test case for BUG#48438.
mysql-test/t/myisam.test:
  A test case for BUG#48438.
parent 44c1a79b
...@@ -306,8 +306,8 @@ void mi_update_status(void* param) ...@@ -306,8 +306,8 @@ void mi_update_status(void* param)
(long) info->s->state.state.data_file_length)); (long) info->s->state.state.data_file_length));
#endif #endif
info->s->state.state= *info->state; info->s->state.state= *info->state;
info->state= &info->s->state.state;
} }
info->state= &info->s->state.state;
info->append_insert_at_end= 0; info->append_insert_at_end= 0;
/* /*
......
...@@ -1898,4 +1898,17 @@ CHECKSUM TABLE t1 EXTENDED; ...@@ -1898,4 +1898,17 @@ CHECKSUM TABLE t1 EXTENDED;
Table Checksum Table Checksum
test.t1 467455460 test.t1 467455460
DROP TABLE t1; DROP TABLE t1;
#
# BUG#48438 - crash with error in unioned query against merge table and view...
#
SET GLOBAL table_cache=3;
CREATE TABLE t1(a INT);
SELECT 1 FROM t1 AS a1, t1 AS a2, t1 AS a3, t1 AS a4 FOR UPDATE;
1
SELECT TABLE_ROWS, DATA_LENGTH FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1';
TABLE_ROWS DATA_LENGTH
0 0
DROP TABLE t1;
SET GLOBAL table_cache=DEFAULT;
End of 5.0 tests End of 5.0 tests
...@@ -1239,4 +1239,15 @@ CHECKSUM TABLE t1 EXTENDED; ...@@ -1239,4 +1239,15 @@ CHECKSUM TABLE t1 EXTENDED;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # BUG#48438 - crash with error in unioned query against merge table and view...
--echo #
SET GLOBAL table_cache=3;
CREATE TABLE t1(a INT);
SELECT 1 FROM t1 AS a1, t1 AS a2, t1 AS a3, t1 AS a4 FOR UPDATE;
SELECT TABLE_ROWS, DATA_LENGTH FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1';
DROP TABLE t1;
SET GLOBAL table_cache=DEFAULT;
--echo End of 5.0 tests --echo End of 5.0 tests
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