List:Commits« Previous MessageNext Message »
From:gluh Date:December 7 2007 11:14am
Subject:bk commit into 5.1 tree (gluh:1.2679) BUG#32167
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of gluh. When gluh does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

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.

  mysql-test/r/partition.result@stripped, 2007-12-07 15:14:49+04:00, gluh@stripped +8 -0
    test result

  mysql-test/r/symlink.result@stripped, 2007-12-07 15:14:49+04:00, gluh@stripped +17 -30
    result fix

  mysql-test/t/partition.test@stripped, 2007-12-07 15:14:49+04:00, gluh@stripped +16 -2
    test case

  mysql-test/t/symlink.test@stripped, 2007-12-07 15:14:50+04:00, gluh@stripped +20 -50
    removed BUG#32111, BUG#29325.
    added test case for 32167 

  sql/mysql_priv.h@stripped, 2007-12-07 15:14:50+04:00, gluh@stripped +2 -1
    new variable mysql_unpacked_real_data_home

  sql/mysqld.cc@stripped, 2007-12-07 15:14:50+04:00, gluh@stripped +4 -0
    new variable mysql_unpacked_real_data_home

  sql/sql_parse.cc@stripped, 2007-12-07 15:14:50+04:00, gluh@stripped +43 -0
    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

  sql/sql_yacc.yy@stripped, 2007-12-07 15:14:50+04:00, gluh@stripped +41 -6
    added check for data home directory

diff -Nrup a/mysql-test/r/partition.result b/mysql-test/r/partition.result
--- a/mysql-test/r/partition.result	2007-11-27 12:28:05 +04:00
+++ b/mysql-test/r/partition.result	2007-12-07 15:14:49 +04:00
@@ -1307,4 +1307,12 @@ ERROR 42000: You have an error in your S
 ALTER TABLE t1 ANALYZE PARTITION p1 EXTENDED;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'EXTENDED' at line 1
 DROP TABLE t1;
+CREATE TABLE t1(a INT)
+PARTITION BY KEY (a)
+(PARTITION p0 DATA DIRECTORY 'TEST_DIR/master-data/test');
+ERROR HY000: Incorrect arguments to DATA DIRECORY
+CREATE TABLE t1(a INT)
+PARTITION BY KEY (a)
+(PARTITION p0 INDEX DIRECTORY 'TEST_DIR/master-data/test');
+ERROR HY000: Incorrect arguments to INDEX DIRECORY
 End of 5.1 tests
diff -Nrup a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result
--- a/mysql-test/r/symlink.result	2007-11-12 21:55:50 +04:00
+++ b/mysql-test/r/symlink.result	2007-12-07 15:14:49 +04:00
@@ -99,23 +99,17 @@ t1	CREATE TABLE `t1` (
   `b` int(11) DEFAULT NULL
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 drop table t1;
-CREATE TABLE t1(a INT)
-DATA DIRECTORY='TEST_DIR/master-data/mysql'
-INDEX DIRECTORY='TEST_DIR/master-data/mysql';
-RENAME TABLE t1 TO user;
-ERROR HY000: Can't create/write to file 'TEST_DIR/master-data/mysql/user.MYI' (Errcode: 17)
-DROP TABLE t1;
 show create table t1;
 Table	Create Table
 t1	CREATE TABLE `t1` (
   `i` int(11) DEFAULT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='/home/gluh/MySQL/Bugs/5.1.22167/mysql-test/var/tmp/'
 drop table t1;
 show create table t1;
 Table	Create Table
 t1	CREATE TABLE `t1` (
   `i` int(11) DEFAULT NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 INDEX DIRECTORY='/home/gluh/MySQL/Bugs/5.1.22167/mysql-test/var/tmp/'
 drop table t1;
 show create table t1;
 Table	Create Table
@@ -139,26 +133,19 @@ a
 42
 drop table t1;
 End of 4.1 tests
-CREATE DATABASE db1;
-CREATE DATABASE db2;
-USE db2;
-INSERT INTO db2.t1 VALUES (1);
-SELECT * FROM db2.t1;
-b
-1
-RESET QUERY CACHE;
-USE db1;
-SET SESSION keep_files_on_create = TRUE;
-CREATE TABLE t1 (a INT) ENGINE MYISAM;
-Got one of the listed errors
-CREATE TABLE t3 (a INT) Engine=MyISAM;
-INSERT INTO t3 VALUES (1),(2),(3);
-TRUNCATE TABLE t3;
-SELECT * from t3;
-a
-SET SESSION keep_files_on_create = DEFAULT;
-DROP TABLE db2.t1, db1.t3;
-DROP DATABASE db1;
-DROP DATABASE db2;
-USE test;
+CREATE TABLE t1(a INT)
+INDEX DIRECTORY='TEST_DIR/master-data/mysql';
+ERROR HY000: Incorrect arguments to INDEX DIRECORY
+CREATE TABLE t1(a INT)
+DATA DIRECTORY='TEST_DIR/master-data/test';
+ERROR HY000: Incorrect arguments to DATA DIRECORY
+CREATE TABLE t1(a INT)
+DATA DIRECTORY='/home/gluh/MySQL/Bugs/5.1.22167/mysql-test/var/master-data/';
+DROP TABLE t1;
+CREATE TABLE t1(a INT)
+INDEX DIRECTORY='/home/gluh/MySQL/Bugs/5.1.22167/mysql-test/var/master-data';
+DROP TABLE t1;
+CREATE TABLE t1(a INT)
+INDEX DIRECTORY='/home/gluh/MySQL/Bugs/5.1.22167/mysql-test/var/master-data_var';
+ERROR HY000: Can't create/write to file '/home/gluh/MySQL/Bugs/5.1.22167/mysql-test/var/master-data_var/t1.MYI' (Errcode: 2)
 End of 5.0 tests
diff -Nrup a/mysql-test/t/partition.test b/mysql-test/t/partition.test
--- a/mysql-test/t/partition.test	2007-11-27 22:20:08 +04:00
+++ b/mysql-test/t/partition.test	2007-12-07 15:14:49 +04:00
@@ -1407,8 +1407,8 @@ eval create table t2 (i int )
 partition by range (i)
 (
     partition p01 values less than (1000)
-    data directory="$MYSQLTEST_VARDIR/master-data/test/"
-    index directory="$MYSQLTEST_VARDIR/master-data/test/"
+    data directory="$MYSQLTEST_VARDIR/tmp/"
+    index directory="$MYSQLTEST_VARDIR/tmp/"
 );
 enable_query_log;
 
@@ -1555,5 +1555,19 @@ ALTER TABLE t1 OPTIMIZE PARTITION p1 EXT
 --error 1064
 ALTER TABLE t1 ANALYZE PARTITION p1 EXTENDED;
 DROP TABLE t1;
+
+#
+# Bug#32167: another privilege bypass with DATA/INDEX DIRECTORY
+#
+--replace_result $MYSQLTEST_VARDIR TEST_DIR
+--error 1210
+eval CREATE TABLE t1(a INT)
+PARTITION BY KEY (a)
+(PARTITION p0 DATA DIRECTORY '$MYSQLTEST_VARDIR/master-data/test');
+--replace_result $MYSQLTEST_VARDIR TEST_DIR
+--error 1210
+eval CREATE TABLE t1(a INT)
+PARTITION BY KEY (a)
+(PARTITION p0 INDEX DIRECTORY '$MYSQLTEST_VARDIR/master-data/test');
 
 --echo End of 5.1 tests
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;
-
-#
 # Test specifying DATA DIRECTORY that is the same as what would normally
 # have been chosen. (Bug #8707)
 #
 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)
+# 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;
-
-USE db1;
-
-#no warning from create table
-SET SESSION keep_files_on_create = TRUE;
---disable_abort_on_error
---error 1,1
-CREATE TABLE t1 (a INT) ENGINE MYISAM;
---enable_abort_on_error
-
-CREATE TABLE t3 (a INT) Engine=MyISAM;
-INSERT INTO t3 VALUES (1),(2),(3);
-TRUNCATE TABLE t3;
-SELECT * from t3;
-
-SET SESSION keep_files_on_create = DEFAULT;
-
-DROP TABLE db2.t1, db1.t3;
-DROP DATABASE db1;
-DROP DATABASE db2;
-USE test;
-
+--replace_result $MYSQLTEST_VARDIR TEST_DIR
+--error 1210
+eval CREATE TABLE t1(a INT)
+INDEX DIRECTORY='$MYSQLTEST_VARDIR/master-data/mysql';
+--replace_result $MYSQLTEST_VARDIR TEST_DIR
+--error 1210
+eval CREATE TABLE t1(a INT)
+DATA DIRECTORY='$MYSQLTEST_VARDIR/master-data/test';
+eval CREATE TABLE t1(a INT)
+DATA DIRECTORY='$MYSQLTEST_VARDIR/master-data/';
+DROP TABLE t1;
+eval CREATE TABLE t1(a INT)
+INDEX DIRECTORY='$MYSQLTEST_VARDIR/master-data';
+DROP TABLE t1;
+--error 1
+eval CREATE TABLE t1(a INT)
+INDEX DIRECTORY='$MYSQLTEST_VARDIR/master-data_var';
 
 --echo End of 5.0 tests
diff -Nrup a/sql/mysql_priv.h b/sql/mysql_priv.h
--- a/sql/mysql_priv.h	2007-11-29 15:42:23 +04:00
+++ b/sql/mysql_priv.h	2007-12-07 15:14:50 +04:00
@@ -709,6 +709,7 @@ bool check_string_byte_length(LEX_STRING
 bool check_string_char_length(LEX_STRING *str, const char *err_msg,
                               uint max_char_length, CHARSET_INFO *cs,
                               bool no_error);
+bool test_if_data_home_dir(const char *dir);
 
 bool parse_sql(THD *thd,
                class Lex_input_stream *lip,
@@ -1733,7 +1734,7 @@ extern time_t server_start_time;
 #if defined MYSQL_SERVER || defined INNODB_COMPATIBILITY_HOOKS
 extern uint mysql_data_home_len;
 extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
-            mysql_real_data_home[];
+            mysql_real_data_home[], mysql_unpacked_real_data_home[];
 #endif /* MYSQL_SERVER || INNODB_COMPATIBILITY_HOOKS */
 #ifdef MYSQL_SERVER
 extern char *opt_mysql_tmpdir, mysql_charsets_dir[],
diff -Nrup a/sql/mysqld.cc b/sql/mysqld.cc
--- a/sql/mysqld.cc	2007-11-28 20:08:25 +04:00
+++ b/sql/mysqld.cc	2007-12-07 15:14:50 +04:00
@@ -489,6 +489,7 @@ char mysql_real_data_home[FN_REFLEN],
      language[FN_REFLEN], reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN],
      *opt_init_file, *opt_tc_log_file,
      def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
+char mysql_unpacked_real_data_home[FN_REFLEN];
 uint reg_ext_length;
 const key_map key_map_empty(0);
 key_map key_map_full(0);                        // Will be initialized later
@@ -8003,6 +8004,9 @@ static void fix_paths(void)
     pos[1]= 0;
   }
   convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
+  (void) fn_format(buff, mysql_real_data_home, "", "",
+                   (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
+  (void) unpack_dirname(mysql_unpacked_real_data_home, buff);
   convert_dirname(language,language,NullS);
   (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
   (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
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,
+                        (const uchar*) conv_path, home_dir_len,
+                        (const uchar*) mysql_unpacked_real_data_home,
+                        home_dir_len))
+        DBUG_RETURN(1);
+    }
+    else if (!memcmp(conv_path, mysql_unpacked_real_data_home, home_dir_len))
+      DBUG_RETURN(1);
+  }
+  DBUG_RETURN(0);
+}
+
+
 extern int MYSQLparse(void *thd); // from sql_yacc.cc
 
 
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
@@ -1113,6 +1113,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
         IDENT_sys TEXT_STRING_sys TEXT_STRING_literal
         NCHAR_STRING opt_component key_cache_name
         sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty
+        data_home_dir
 
 %type <lex_str_ptr>
         opt_table_alias
@@ -4085,10 +4086,24 @@ opt_part_option:
           { Lex->part_info->curr_part_elem->part_max_rows= (ha_rows) $3; }
         | MIN_ROWS opt_equal real_ulonglong_num
           { Lex->part_info->curr_part_elem->part_min_rows= (ha_rows) $3; }
-        | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
-          { Lex->part_info->curr_part_elem->data_file_name= $4.str; }
-        | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
-          { Lex->part_info->curr_part_elem->index_file_name= $4.str; }
+        | DATA_SYM DIRECTORY_SYM opt_equal data_home_dir
+          {
+            if (!$4.str)
+            {
+              my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECORY");
+              MYSQL_YYABORT;
+            }
+            Lex->part_info->curr_part_elem->data_file_name= $4.str;
+          }
+        | INDEX_SYM DIRECTORY_SYM opt_equal data_home_dir
+          {
+            if (!$4.str)
+            {
+              my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECORY");
+              MYSQL_YYABORT;
+            }
+            Lex->part_info->curr_part_elem->index_file_name= $4.str;
+          }
         | COMMENT_SYM opt_equal TEXT_STRING_sys
           { Lex->part_info->curr_part_elem->part_comment= $3.str; }
         ;
@@ -4284,13 +4299,23 @@ create_table_option:
             Lex->create_info.merge_insert_method= $3;
             Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;
           }
-        | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
+        | DATA_SYM DIRECTORY_SYM opt_equal data_home_dir
           {
+            if (!$4.str)
+            {
+              my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECORY");
+              MYSQL_YYABORT;
+            }
             Lex->create_info.data_file_name= $4.str;
             Lex->create_info.used_fields|= HA_CREATE_USED_DATADIR;
           }
-        | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
+        | INDEX_SYM DIRECTORY_SYM opt_equal data_home_dir
           {
+            if (!$4.str)
+            {
+              my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECORY");
+              MYSQL_YYABORT;
+            }
             Lex->create_info.index_file_name= $4.str;
             Lex->create_info.used_fields|= HA_CREATE_USED_INDEXDIR;
           }
@@ -10203,6 +10228,16 @@ user:
             */
             bzero($$, sizeof(LEX_USER));
           }
+        ;
+
+data_home_dir:
+        TEXT_STRING_sys
+        {
+          if (test_if_data_home_dir($1.str))
+            bzero(&$$, sizeof(LEX_STRING));
+          else
+            $$= $1;
+        }
         ;
 
 /* Keyword that we allow for identifiers (except SP labels) */
Thread
bk commit into 5.1 tree (gluh:1.2679) BUG#32167gluh7 Dec
  • Re: bk commit into 5.1 tree (gluh:1.2679) BUG#32167Sergei Golubchik12 Dec