List:Commits« Previous MessageNext Message »
From:gluh Date:November 30 2007 8:11am
Subject:bk commit into 4.0 tree (gluh:1.2198) BUG#32167
View as plain text  
Below is the list of changes that have just been committed into a local
4.0 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-11-30 12:11:33+04:00, gluh@stripped +3 -0
  Bug#32167 another privilege bypass with DATA/INDEX DIRECORY(3rd version)
  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/symlink.result@stripped, 2007-11-30 12:11:33+04:00, gluh@stripped +12 -0
    test result

  mysql-test/t/symlink.test@stripped, 2007-11-30 12:11:33+04:00, gluh@stripped +17 -0
    test case

  sql/sql_parse.cc@stripped, 2007-11-30 12:11:33+04:00, gluh@stripped +70 -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.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	gluh
# Host:	eagle.(none)
# Root:	/home/gluh/MySQL/Bugs/4.0

--- 1.397/sql/sql_parse.cc	2006-04-26 04:41:10 +05:00
+++ 1.398/sql/sql_parse.cc	2007-11-30 12:11:33 +04:00
@@ -67,6 +67,8 @@ static bool create_total_list(THD *thd, 
 			      TABLE_LIST **result, bool skip_first);
 static bool check_one_table_access(THD *thd, ulong want_access,
 				   TABLE_LIST *table, bool no_errors);
+static bool test_if_data_home_dir(const char *dir, const char *conv_home_dir,
+                                  uint home_dir_len);
 
 
 const char *any_db="*any*";	// Special symbol for check_access
@@ -1652,6 +1654,8 @@ mysql_execute_command(void)
 
   case SQLCOM_CREATE_TABLE:
   {
+    uint home_dir_len= 0;
+    char real_home_dir[FN_REFLEN], conv_home_dir[FN_REFLEN];
     ulong want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ?
 		      CREATE_TMP_ACL : CREATE_ACL);
     if (!tables->db)
@@ -1681,6 +1685,32 @@ mysql_execute_command(void)
 #ifndef HAVE_READLINK
     lex->create_info.data_file_name=lex->create_info.index_file_name=0;
 #else
+
+    if (lex->create_info.data_file_name ||
+        lex->create_info.index_file_name)
+    {
+      (void) fn_format(real_home_dir, mysql_real_data_home, "", "",
+                       (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
+      home_dir_len= unpack_dirname(conv_home_dir, real_home_dir);
+    }
+
+    if (lex->create_info.data_file_name &&
+        test_if_data_home_dir(lex->create_info.data_file_name,
+                              conv_home_dir, home_dir_len))
+    {
+      my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECORY");
+      res= -1;
+      break;
+    }
+    if (lex->create_info.index_file_name &&
+        test_if_data_home_dir(lex->create_info.index_file_name,
+                              conv_home_dir, home_dir_len))
+    {
+      my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECORY");
+      res= -1;
+      break;
+    }
+
     /* Fix names if symlinked tables */
     if (append_file_to_dir(thd, &lex->create_info.data_file_name,
 			   tables->real_name) ||
@@ -4040,4 +4070,44 @@ static bool check_multi_update_lock(THD 
   
 error:
   DBUG_RETURN(res);
+}
+
+
+/*
+  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  
+*/
+
+static bool test_if_data_home_dir(const char *dir, const char *conv_home_dir,
+                                  uint home_dir_len)
+{
+  uint dir_len;
+  char path[FN_REFLEN], conv_path[FN_REFLEN];
+  DBUG_ENTER("test_if_data_home_dir");
+  
+  (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(default_charset_info, (const uchar*) conv_path, home_dir_len,
+                        (const uchar*) conv_home_dir, home_dir_len))
+        DBUG_RETURN(1);
+    }
+    else if (!memcmp(conv_path, conv_home_dir, home_dir_len))
+      DBUG_RETURN(1);
+  }
+  DBUG_RETURN(0);
 }

--- 1.7/mysql-test/r/symlink.result	2003-12-13 00:26:56 +04:00
+++ 1.8/mysql-test/r/symlink.result	2007-11-30 12:11:33 +04:00
@@ -84,3 +84,15 @@ t1	CREATE TABLE `t1` (
   `b` int(11) default NULL
 ) TYPE=MyISAM
 drop table t1;
+CREATE TABLE t1(a INT)
+DATA DIRECTORY='TEST_DIR/var/master-data/test';
+Wrong arguments to DATA DIRECORY
+CREATE TABLE t1(a INT)
+DATA DIRECTORY='TEST_DIR/var/master-data/';
+Wrong arguments to DATA DIRECORY
+CREATE TABLE t1(a INT)
+INDEX DIRECTORY='TEST_DIR/var/master-data';
+Wrong arguments to INDEX DIRECORY
+CREATE TABLE t1(a INT)
+INDEX DIRECTORY='TEST_DIR/var/master-data_var';
+Can't create/write to file 'TEST_DIR/var/master-data_var/t1.MYI' (Errcode: 2)

--- 1.6/mysql-test/t/symlink.test	2003-12-13 00:26:56 +04:00
+++ 1.7/mysql-test/t/symlink.test	2007-11-30 12:11:33 +04:00
@@ -112,3 +112,20 @@ eval alter table t1 index directory="$MY
 enable_query_log;
 show create table t1;
 drop table t1;
+
+#
+# Bug#32167 another privilege bypass with DATA/INDEX DIRECORY
+#
+--replace_result $MYSQL_TEST_DIR TEST_DIR
+--error 1210
+eval CREATE TABLE t1(a INT)
+DATA DIRECTORY='$MYSQL_TEST_DIR/var/master-data/test';
+--error 1210
+eval CREATE TABLE t1(a INT)
+DATA DIRECTORY='$MYSQL_TEST_DIR/var/master-data/';
+--error 1210
+eval CREATE TABLE t1(a INT)
+INDEX DIRECTORY='$MYSQL_TEST_DIR/var/master-data';
+--error 1
+eval CREATE TABLE t1(a INT)
+INDEX DIRECTORY='$MYSQL_TEST_DIR/var/master-data_var';
Thread
bk commit into 4.0 tree (gluh:1.2198) BUG#32167gluh30 Nov