File mysql-5.0.67-CVE-2008-7247.patch of Package mysql
Index: sql/sql_parse.cc
===================================================================
--- sql/sql_parse.cc.orig
+++ sql/sql_parse.cc
@@ -3094,17 +3094,45 @@ mysql_execute_command(THD *thd)
create_info.data_file_name= create_info.index_file_name= NULL;
#else
- if (test_if_data_home_dir(lex->create_info.data_file_name))
+ char dirpath[FN_REFLEN];
+
+ /*
+ data_file_name and index_file_name include the table name without
+ extension. Mostly this does not refer to an existing file. When
+ comparing data_file_name or index_file_name against the data
+ directory, we try to resolve all symbolic links. On some systems,
+ we use realpath(3) for the resolution. This returns ENOENT if the
+ resolved path does not refer to an existing file. my_realpath()
+ does then copy the requested path verbatim, without symlink
+ resolution. Thereafter the comparison can fail even if the
+ requested path is within the data directory. E.g. if symlinks to
+ another file system are used. To make realpath(3) return the
+ resolved path, we strip the table name and compare the directory
+ path only. If the directory doesn't exist either, table creation
+ will fail anyway. But we can't strip blindly anything so we keep
+ the previous check too, just to be sure.
+ */
+ if (lex->create_info.data_file_name)
{
- my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECTORY");
- res= -1;
- break;
+ dirname_part(dirpath, lex->create_info.data_file_name);
+ if (test_if_data_home_dir(dirpath)
+ || test_if_data_home_dir(lex->create_info.data_file_name) )
+ {
+ my_error(ER_WRONG_ARGUMENTS, MYF(0), "DATA DIRECTORY");
+ res= -1;
+ break;
+ }
}
- if (test_if_data_home_dir(lex->create_info.index_file_name))
+ if (lex->create_info.index_file_name)
{
- my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECTORY");
- res= -1;
- break;
+ dirname_part(dirpath, lex->create_info.index_file_name);
+ if (test_if_data_home_dir(dirpath)
+ || test_if_data_home_dir(lex->create_info.index_file_name) )
+ {
+ my_error(ER_WRONG_ARGUMENTS, MYF(0), "INDEX DIRECTORY");
+ res= -1;
+ break;
+ }
}
/* Fix names if symlinked tables */
Index: libmysqld/sql_parse.cc
===================================================================
--- libmysqld/sql_parse.cc.orig
+++ libmysqld/sql_parse.cc
@@ -3095,17 +3095,45 @@ mysql_execute_command(THD *thd)
create_info.data_file_name= create_info.index_file_name= NULL;
#else
- if (test_if_data_home_dir(lex->create_info.data_file_name))
+ char dirpath[FN_REFLEN];
+
+ /*
+ data_file_name and index_file_name include the table name without
+ extension. Mostly this does not refer to an existing file. When
+ comparing data_file_name or index_file_name against the data
+ directory, we try to resolve all symbolic links. On some systems,
+ we use realpath(3) for the resolution. This returns ENOENT if the
+ resolved path does not refer to an existing file. my_realpath()
+ does then copy the requested path verbatim, without symlink
+ resolution. Thereafter the comparison can fail even if the
+ requested path is within the data directory. E.g. if symlinks to
+ another file system are used. To make realpath(3) return the
+ resolved path, we strip the table name and compare the directory
+ path only. If the directory doesn't exist either, table creation
+ will fail anyway. But we can't strip blindly anything so we keep
+ the previous check too, just to be sure.
+ */
+ if (lex->create_info.data_file_name)
{
- my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECORY");
- res= -1;
- break;
+ dirname_part(dirpath, lex->create_info.data_file_name);
+ if (test_if_data_home_dir(dirpath)
+ || test_if_data_home_dir(lex->create_info.data_file_name) )
+ {
+ my_error(ER_WRONG_ARGUMENTS, MYF(0), "DATA DIRECTORY");
+ res= -1;
+ break;
+ }
}
- if (test_if_data_home_dir(lex->create_info.index_file_name))
+ if (lex->create_info.index_file_name)
{
- my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECORY");
- res= -1;
- break;
+ dirname_part(dirpath, lex->create_info.index_file_name);
+ if (test_if_data_home_dir(dirpath)
+ || test_if_data_home_dir(lex->create_info.index_file_name) )
+ {
+ my_error(ER_WRONG_ARGUMENTS, MYF(0), "INDEX DIRECTORY");
+ res= -1;
+ break;
+ }
}
/* Fix names if symlinked tables */