From 6ac3d502d7dfd51af8e502404d7732f81feb4a5b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 9 Nov 2007 23:22:00 +0100 Subject: Bug#32091: Security breach via directory changes Problem: the table's INDEX and DATA DIR was taken directly from the table's first partition. This allowed rename attack similar to bug#32111 when ALTER TABLE REMOVE PARTITIONING Solution: Silently ignore the INDEX/DATA DIR for the table. (Like some other storage engines do). Partitioned tables do not support DATA/INDEX DIR on the table level, only on its partitions. mysql-test/r/partition_mgm.result: Bug#32091: Security breach via directory changes test result mysql-test/t/partition_mgm.test: Bug#32091: Security breach via directory changes test case sql/ha_partition.cc: Bug#32091: Security breach via directory changes Do not use the first partition's DATA/INDEX DIR as the table's DATA/INDEX DIR. (A partitioned table do not have support for DATA/ INDEX DIR, only its partitions do) --- mysql-test/r/partition_mgm.result | 81 +++++++++++++++++++++++++++ mysql-test/t/partition_mgm.test | 113 +++++++++++++++++++++++++++++++++++++- 2 files changed, 192 insertions(+), 2 deletions(-) (limited to 'mysql-test') diff --git a/mysql-test/r/partition_mgm.result b/mysql-test/r/partition_mgm.result index 04ac603fea7..7d2c159bb15 100644 --- a/mysql-test/r/partition_mgm.result +++ b/mysql-test/r/partition_mgm.result @@ -1,4 +1,85 @@ DROP TABLE IF EXISTS t1; +# Creating two non colliding tables mysqltest2.t1 and test.t1 +# test.t1 have partitions in mysqltest2-directory! +# user root: +GRANT USAGE ON test.* TO mysqltest_1@localhost; +CREATE DATABASE mysqltest2; +USE mysqltest2; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0); +# user mysqltest_1: +USE test; +CREATE TABLE t1 (a INT) +PARTITION BY LIST (a) ( +PARTITION p0 VALUES IN (0) +DATA DIRECTORY 'MYSQLTEST_VARDIR/master-data/mysqltest2' + INDEX DIRECTORY 'MYSQLTEST_VARDIR/master-data/mysqltest2', +PARTITION p1 VALUES IN (1) +DATA DIRECTORY 'MYSQLTEST_VARDIR/master-data/test' + INDEX DIRECTORY 'MYSQLTEST_VARDIR/master-data/test', +PARTITION p2 VALUES IN (2) +); +# without the patch for bug#32091 this would create +# files mysqltest2/t1.MYD + .MYI and possible overwrite +# the mysqltest2.t1 table (depending on bug#32111) +ALTER TABLE t1 REMOVE PARTITIONING; +INSERT INTO t1 VALUES (1); +SELECT * FROM t1; +a +1 +# user root: +USE mysqltest2; +FLUSH TABLES; +# if the patch works, this should be different +# and before the patch they were the same! +SELECT * FROM t1; +a +0 +USE test; +SELECT * FROM t1; +a +1 +DROP TABLE t1; +DROP DATABASE mysqltest2; +# test that symlinks can not overwrite files when CREATE TABLE +# user root: +CREATE DATABASE mysqltest2; +USE mysqltest2; +CREATE TABLE t1 (a INT) +PARTITION BY LIST (a) ( +PARTITION p0 VALUES IN (0) +DATA DIRECTORY 'MYSQLTEST_VARDIR/master-data/mysqltest2' + INDEX DIRECTORY 'MYSQLTEST_VARDIR/master-data/mysqltest2', +PARTITION p1 VALUES IN (1) +DATA DIRECTORY 'MYSQLTEST_VARDIR/master-data/test' + INDEX DIRECTORY 'MYSQLTEST_VARDIR/master-data/test' + ); +# user mysqltest_1: +USE test; +CREATE TABLE t1 (a INT) +PARTITION BY LIST (a) ( +PARTITION p0 VALUES IN (0) +DATA DIRECTORY 'MYSQLTEST_VARDIR/master-data/mysqltest2' + INDEX DIRECTORY 'MYSQLTEST_VARDIR/master-data/mysqltest2', +PARTITION p1 VALUES IN (1) +DATA DIRECTORY 'MYSQLTEST_VARDIR/master-data/test' + INDEX DIRECTORY 'MYSQLTEST_VARDIR/master-data/test' + ); +ERROR HY000: Can't create/write to file 'MYSQLTEST_VARDIR/master-data/mysqltest2/t1#P#p0.MYI' (Errcode: 17) +CREATE TABLE t1 (a INT) +PARTITION BY LIST (a) ( +PARTITION p0 VALUES IN (0) +DATA DIRECTORY 'MYSQLTEST_VARDIR/master-data/test' + INDEX DIRECTORY 'MYSQLTEST_VARDIR/master-data/test', +PARTITION p1 VALUES IN (1) +DATA DIRECTORY 'MYSQLTEST_VARDIR/master-data/mysqltest2' + INDEX DIRECTORY 'MYSQLTEST_VARDIR/master-data/mysqltest2' + ); +ERROR HY000: Can't create/write to file 'MYSQLTEST_VARDIR/master-data/test/t1#P#p1.MYI' (Errcode: 17) +# user root (cleanup): +DROP DATABASE mysqltest2; +USE test; +REVOKE USAGE ON *.* FROM mysqltest_1@localhost; create table t1 (a int) partition by range (a) subpartition by key (a) diff --git a/mysql-test/t/partition_mgm.test b/mysql-test/t/partition_mgm.test index a06f8d1aee5..a405e15ec16 100644 --- a/mysql-test/t/partition_mgm.test +++ b/mysql-test/t/partition_mgm.test @@ -1,7 +1,116 @@ -- source include/have_partition.inc ---disable_warnings +-- disable_warnings DROP TABLE IF EXISTS t1; ---enable_warnings +-- enable_warnings + +# +# Bug 32091: Security breach via directory changes +# +# The below test shows that a pre-existing table mysqltest2.t1 cannot be +# replaced by a user with no rights in 'mysqltest2'. The altered table +# test.t1 will be altered (remove partitioning) into the test directory +# and having its partitions removed from the mysqltest2 directory. +# (the partitions data files are named #P#.MYD +# and will not collide with a non partitioned table's data files.) +# NOTE: the privileges on files and directories are the same for all +# database users in mysqld, though mysqld enforces privileges on +# the database and table levels which in turn maps to directories and +# files, but not the other way around (any db-user can use any +# directory or file that the mysqld-process can use, via DATA/INDEX DIR) +# this is the security flaw that was used in bug#32091 and bug#32111 +-- echo # Creating two non colliding tables mysqltest2.t1 and test.t1 +-- echo # test.t1 have partitions in mysqltest2-directory! +-- echo # user root: + GRANT USAGE ON test.* TO mysqltest_1@localhost; + CREATE DATABASE mysqltest2; + USE mysqltest2; + CREATE TABLE t1 (a INT); + INSERT INTO t1 VALUES (0); +connect(con1,localhost,mysqltest_1,,); +-- echo # user mysqltest_1: + USE test; + -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR + eval CREATE TABLE t1 (a INT) + PARTITION BY LIST (a) ( + PARTITION p0 VALUES IN (0) + DATA DIRECTORY '$MYSQLTEST_VARDIR/master-data/mysqltest2' + INDEX DIRECTORY '$MYSQLTEST_VARDIR/master-data/mysqltest2', + PARTITION p1 VALUES IN (1) + DATA DIRECTORY '$MYSQLTEST_VARDIR/master-data/test' + INDEX DIRECTORY '$MYSQLTEST_VARDIR/master-data/test', + PARTITION p2 VALUES IN (2) + ); + -- echo # without the patch for bug#32091 this would create + -- echo # files mysqltest2/t1.MYD + .MYI and possible overwrite + -- echo # the mysqltest2.t1 table (depending on bug#32111) + -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR + ALTER TABLE t1 REMOVE PARTITIONING; + INSERT INTO t1 VALUES (1); + SELECT * FROM t1; +connection default; +-- echo # user root: + USE mysqltest2; + FLUSH TABLES; + -- echo # if the patch works, this should be different + -- echo # and before the patch they were the same! + SELECT * FROM t1; + USE test; + SELECT * FROM t1; + DROP TABLE t1; + DROP DATABASE mysqltest2; +# The below test shows that a pre-existing partition can not be +# destroyed by a new partition from another table. +# (Remember that a table or partition that uses the DATA/INDEX DIR +# is symlinked and thus has +# 1. the real file in the DATA/INDEX DIR and +# 2. a symlink in its default database directory pointing to +# the real file. +# So it is using/blocking 2 files in (in 2 different directories +-- echo # test that symlinks can not overwrite files when CREATE TABLE +-- echo # user root: + CREATE DATABASE mysqltest2; + USE mysqltest2; + -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR + eval CREATE TABLE t1 (a INT) + PARTITION BY LIST (a) ( + PARTITION p0 VALUES IN (0) + DATA DIRECTORY '$MYSQLTEST_VARDIR/master-data/mysqltest2' + INDEX DIRECTORY '$MYSQLTEST_VARDIR/master-data/mysqltest2', + PARTITION p1 VALUES IN (1) + DATA DIRECTORY '$MYSQLTEST_VARDIR/master-data/test' + INDEX DIRECTORY '$MYSQLTEST_VARDIR/master-data/test' + ); +connection con1; +-- echo # user mysqltest_1: + USE test; + -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR + -- error 1 + eval CREATE TABLE t1 (a INT) + PARTITION BY LIST (a) ( + PARTITION p0 VALUES IN (0) + DATA DIRECTORY '$MYSQLTEST_VARDIR/master-data/mysqltest2' + INDEX DIRECTORY '$MYSQLTEST_VARDIR/master-data/mysqltest2', + PARTITION p1 VALUES IN (1) + DATA DIRECTORY '$MYSQLTEST_VARDIR/master-data/test' + INDEX DIRECTORY '$MYSQLTEST_VARDIR/master-data/test' + ); + -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR + -- error 1 + eval CREATE TABLE t1 (a INT) + PARTITION BY LIST (a) ( + PARTITION p0 VALUES IN (0) + DATA DIRECTORY '$MYSQLTEST_VARDIR/master-data/test' + INDEX DIRECTORY '$MYSQLTEST_VARDIR/master-data/test', + PARTITION p1 VALUES IN (1) + DATA DIRECTORY '$MYSQLTEST_VARDIR/master-data/mysqltest2' + INDEX DIRECTORY '$MYSQLTEST_VARDIR/master-data/mysqltest2' + ); +connection default; +-- echo # user root (cleanup): + DROP DATABASE mysqltest2; + USE test; + REVOKE USAGE ON *.* FROM mysqltest_1@localhost; + disconnect con1; # # Bug 21143: mysqld hang when error in number of subparts in -- cgit v1.2.1