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 15:54:55+04:00, gluh@stripped +5 -0
Bug#32167 another privilege bypass with DATA/INDEX DIRECORY
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 15:54:55+04:00, gluh@stripped +11 -5
test result
mysql-test/t/symlink.test@stripped, 2007-11-30 15:54:55+04:00, gluh@stripped +11 -6
test case, test case for BUG#32111 is removed as non working with the current fix
sql/mysql_priv.h@stripped, 2007-11-30 15:54:55+04:00, gluh@stripped +2 -1
new variable mysql_unpacked_real_data_home
sql/mysqld.cc@stripped, 2007-11-30 15:54:55+04:00, gluh@stripped +4 -0
new variable mysql_unpacked_real_data_home
sql/sql_parse.cc@stripped, 2007-11-30 15:54:55+04:00, gluh@stripped +57 -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/Merge/4.0
--- 1.240/sql/mysql_priv.h 2007-07-13 20:50:57 +05:00
+++ 1.241/sql/mysql_priv.h 2007-11-30 15:54:55 +04:00
@@ -681,7 +681,8 @@ void clear_error_message(THD *thd);
extern time_t start_time;
extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
- max_sort_char, mysql_real_data_home[], *charsets_list;
+ max_sort_char, mysql_real_data_home[], *charsets_list,
+ mysql_unpacked_real_data_home[];
extern my_string mysql_tmpdir;
extern const char *command_name[];
extern const char *first_keyword, *localhost, *delayed_user;
--- 1.534/sql/mysqld.cc 2007-02-09 15:03:36 +04:00
+++ 1.535/sql/mysqld.cc 2007-11-30 15:54:55 +04:00
@@ -403,6 +403,7 @@ char mysql_real_data_home[FN_REFLEN],
language[LIBLEN],reg_ext[FN_EXTLEN],
mysql_charsets_dir[FN_REFLEN], *charsets_list,
max_sort_char,*mysqld_user,*mysqld_chroot, *opt_init_file;
+char mysql_unpacked_real_data_home[FN_REFLEN];
char *language_ptr= language;
char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
struct passwd *user_info;
@@ -5328,6 +5329,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);
--- 1.397/sql/sql_parse.cc 2006-04-26 04:41:10 +05:00
+++ 1.398/sql/sql_parse.cc 2007-11-30 15:54:55 +04:00
@@ -67,6 +67,7 @@ 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 *any_db="*any*"; // Special symbol for check_access
@@ -1681,6 +1682,20 @@ mysql_execute_command(void)
#ifndef HAVE_READLINK
lex->create_info.data_file_name=lex->create_info.index_file_name=0;
#else
+
+ if (test_if_data_home_dir(lex->create_info.data_file_name))
+ {
+ my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECORY");
+ res= -1;
+ break;
+ }
+ if (test_if_data_home_dir(lex->create_info.index_file_name))
+ {
+ 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 +4055,46 @@ 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)
+{
+ 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(default_charset_info, (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);
}
--- 1.8/mysql-test/r/symlink.result 2007-11-06 18:09:32 +04:00
+++ 1.9/mysql-test/r/symlink.result 2007-11-30 15:54:55 +04:00
@@ -85,8 +85,14 @@ t1 CREATE TABLE `t1` (
) TYPE=MyISAM
drop table t1;
CREATE TABLE t1(a INT)
-DATA DIRECTORY='TEST_DIR/var/master-data/mysql'
-INDEX DIRECTORY='TEST_DIR/var/master-data/mysql';
-RENAME TABLE t1 TO user;
-Can't create/write to file 'TEST_DIR/var/master-data/mysql/user.MYI' (Errcode: 17)
-DROP TABLE t1;
+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.7/mysql-test/t/symlink.test 2007-11-06 18:09:32 +04:00
+++ 1.8/mysql-test/t/symlink.test 2007-11-30 15:54:55 +04:00
@@ -114,13 +114,18 @@ show create table t1;
drop table t1;
#
-# BUG#32111 - Security Breach via DATA/INDEX DIRECORY and RENAME TABLE
+# 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/mysql'
-INDEX DIRECTORY='$MYSQL_TEST_DIR/var/master-data/mysql';
---replace_result $MYSQL_TEST_DIR TEST_DIR
+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
-RENAME TABLE t1 TO user;
-DROP TABLE t1;
+eval CREATE TABLE t1(a INT)
+INDEX DIRECTORY='$MYSQL_TEST_DIR/var/master-data_var';
| Thread |
|---|
| • bk commit into 4.0 tree (gluh:1.2218) BUG#32167 | gluh | 30 Nov |