Hi!
On Dec 07, gluh@stripped wrote:
> ChangeSet@stripped, 2007-12-07 15:14:52+04:00, gluh@stripped +8 -0
> Bug#32167 another privilege bypass with DATA/INDEX DIRECORY(version for 5.1)
> added new function test_if_data_home_dir() which checks that
> path does not contain mysql data home directory.
> Using of mysql data home directory in
> DATA DIRECTORY & INDEX DIRECTORY is disallowed.
>
> diff -Nrup a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test
> --- a/mysql-test/t/symlink.test 2007-11-12 21:55:50 +04:00
> +++ b/mysql-test/t/symlink.test 2007-12-07 15:14:50 +04:00
> @@ -121,28 +121,16 @@ show create table t1;
> drop table t1;
>
> #
> -# BUG#32111 - Security Breach via DATA/INDEX DIRECORY and RENAME TABLE
> -#
> ---replace_result $MYSQLTEST_VARDIR TEST_DIR
> -eval CREATE TABLE t1(a INT)
> -DATA DIRECTORY='$MYSQLTEST_VARDIR/master-data/mysql'
> -INDEX DIRECTORY='$MYSQLTEST_VARDIR/master-data/mysql';
> ---replace_result $MYSQLTEST_VARDIR TEST_DIR
> ---error 1
> -RENAME TABLE t1 TO user;
> -DROP TABLE t1;
create a different test case for it.
(e.g. create a table symlinked in tmp. and one file in tmp. rename the
table over the file. even better: create a file first. then create a
table with the same name - note an error. create table with a different
name. move over - must be an error)
> -#
> # Test specifying DATA DIRECTORY that is the same as what would normally
> # have been chosen. (Bug #8707)
> #
Delete this test case completely. It tests the case (and see bug#8707)
when data directory is the same as where files would've been created by
default, without data directory clause. It's not possible anymore.
> disable_query_log;
> -eval create table t1 (i int) data directory =
> "$MYSQLTEST_VARDIR/master-data/test/";
> +eval create table t1 (i int) data directory = "$MYSQLTEST_VARDIR/tmp";
> enable_query_log;
> show create table t1;
> drop table t1;
> disable_query_log;
> -eval create table t1 (i int) index directory =
> "$MYSQLTEST_VARDIR/master-data/test/";
> +eval create table t1 (i int) index directory = "$MYSQLTEST_VARDIR/tmp";
> enable_query_log;
> show create table t1;
> drop table t1;
> @@ -187,42 +175,24 @@ drop table t1;
> --echo End of 4.1 tests
>
> #
> -# Bug #29325: create table overwrites .MYD file of other table (datadir)
create a different test case for this bug. e.g. create a file in
datadir. create a table with a matching name. observe the error if
keep_files_on_create is TRUE, no error if it's false.
> +# Bug#32167 another privilege bypass with DATA/INDEX DIRECORY
> #
> -
> -CREATE DATABASE db1;
> -CREATE DATABASE db2;
> -
> -USE db2;
> ---disable_query_log
> -eval CREATE TABLE t1 (b INT) ENGINE MYISAM
> -DATA DIRECTORY = '$MYSQLTEST_VARDIR/master-data/db1/';
> ---enable_query_log
> -
> -INSERT INTO db2.t1 VALUES (1);
> -SELECT * FROM db2.t1;
> -RESET QUERY CACHE;
> -
> diff -Nrup a/sql/sql_parse.cc b/sql/sql_parse.cc
> --- a/sql/sql_parse.cc 2007-11-30 17:12:18 +04:00
> +++ b/sql/sql_parse.cc 2007-12-07 15:14:50 +04:00
> @@ -7277,6 +7277,49 @@ bool check_string_char_length(LEX_STRING
> }
>
>
> +/*
> + Check if path does not contain mysql data home directory
> + SYNOPSIS
> + test_if_data_home_dir()
> + dir directory
> + conv_home_dir converted data home directory
> + home_dir_len converted data home directory length
> +
> + RETURN VALUES
> + 0 ok
> + 1 error
> +*/
> +
> +bool test_if_data_home_dir(const char *dir)
> +{
> + char path[FN_REFLEN], conv_path[FN_REFLEN];
> + uint dir_len, home_dir_len= strlen(mysql_unpacked_real_data_home);
> + DBUG_ENTER("test_if_data_home_dir");
> +
> + if (!dir)
> + DBUG_RETURN(0);
> +
> + (void) fn_format(path, dir, "", "",
> + (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
> + dir_len= unpack_dirname(conv_path, dir);
> +
> + if (home_dir_len < dir_len)
> + {
> + if (lower_case_file_system)
> + {
> + if (!my_strnncoll(&my_charset_latin1,
use character_set_filesystem
> + (const uchar*) conv_path, home_dir_len,
> + (const uchar*) mysql_unpacked_real_data_home,
> + home_dir_len))
> + DBUG_RETURN(1);
> diff -Nrup a/sql/sql_yacc.yy b/sql/sql_yacc.yy
> --- a/sql/sql_yacc.yy 2007-11-30 15:34:23 +04:00
> +++ b/sql/sql_yacc.yy 2007-12-07 15:14:50 +04:00
> +data_home_dir:
> + TEXT_STRING_sys
> + {
> + if (test_if_data_home_dir($1.str))
> + bzero(&$$, sizeof(LEX_STRING));
> + else
> + $$= $1;
> + }
> ;
No, you cannot do run-time checks in the parser. E.g. one could create
a stored procedure which would create a table symlinked in a datadir.
But when mysql is run with a different datadir it'll work.
It's similar to creating a procedure that refers to a table that doesn't
exist. You will get "table not found" error when a procedure is run, not
when it's created.
Regards / Mit vielen GrЭssen,
Sergei
--
__ ___ ___ ____ __
/ |/ /_ __/ __/ __ \/ / Sergei Golubchik <serg@stripped>
/ /|_/ / // /\ \/ /_/ / /__ Principal Software Developer
/_/ /_/\_, /___/\___\_\___/ MySQL GmbH, Dachauer Str. 37, D-80335 MЭnchen
<___/ GeschДftsfЭhrer: Kaj ArnЖ - HRB MЭnchen 162140