[debian-mysql] Bug#480292: CVE-2008-2079: mysql allows local users to bypass certain privilege checks
Devin Carraway
devin at debian.org
Mon Jul 7 08:00:15 UTC 2008
tags 480292 +patch
quit
Here's a patch I'm building for an Etch update to address the problem. It's
pretty close to the same one used in the first fix to this bug, except that it
adds a call to realpath() to resolve all components of the path, and fixes the
argument passing so as not to throw the resolved forms away.
--
Devin \ aqua(at)devin.com, IRC:Requiem; http://www.devin.com
Carraway \ 1024D/E9ABFCD2: 13E7 199E DD1E 65F0 8905 2E43 5395 CA0D E9AB FCD2
-------------- next part --------------
#! /bin/sh /usr/share/dpatch/dpatch-run
## 97_SECURITY_CVE-2008-2079.dpatch by <devin at debian.org>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: Fix for CVE-2008-2079: Some access checks could be bypassed by local
## DP: users creating tables with chosen data or index directory arguments
## DP: later reused by subsequently created tables.
@DPATCH@
diff -aruN mysql-dfsg-5.0-5.0.32.orig/sql/mysql_priv.h mysql-dfsg-5.0-5.0.32/sql/mysql_priv.h
--- mysql-dfsg-5.0-5.0.32.orig/sql/mysql_priv.h 2008-07-06 13:09:21.000000000 -0700
+++ mysql-dfsg-5.0-5.0.32/sql/mysql_priv.h 2008-07-06 13:13:21.000000000 -0700
@@ -1193,6 +1193,7 @@
extern time_t start_time;
extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
mysql_real_data_home[], *opt_mysql_tmpdir, mysql_charsets_dir[],
+ mysql_unpacked_real_data_home[],
def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
#define mysql_tmpdir (my_tmpdir(&mysql_tmpdir_list))
extern MY_TMPDIR mysql_tmpdir_list;
diff -aruN mysql-dfsg-5.0-5.0.32.orig/sql/mysqld.cc mysql-dfsg-5.0-5.0.32/sql/mysqld.cc
--- mysql-dfsg-5.0-5.0.32.orig/sql/mysqld.cc 2006-12-20 03:14:10.000000000 -0800
+++ mysql-dfsg-5.0-5.0.32/sql/mysqld.cc 2008-07-06 13:13:21.000000000 -0700
@@ -437,14 +437,13 @@
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,
+ mysql_unpacked_real_data_home[FN_REFLEN],
def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
-
+char *mysql_data_home= mysql_real_data_home;
const key_map key_map_empty(0);
key_map key_map_full(0); // Will be initialized later
const char *opt_date_time_formats[3];
-
-char *mysql_data_home= mysql_real_data_home;
char server_version[SERVER_VERSION_LENGTH];
char *mysqld_unix_port, *opt_mysql_tmpdir;
const char **errmesg; /* Error messages */
@@ -7356,6 +7355,9 @@
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 -aruN mysql-dfsg-5.0-5.0.32.orig/sql/sql_parse.cc mysql-dfsg-5.0-5.0.32/sql/sql_parse.cc
--- mysql-dfsg-5.0-5.0.32.orig/sql/sql_parse.cc 2008-07-06 13:09:21.000000000 -0700
+++ mysql-dfsg-5.0-5.0.32/sql/sql_parse.cc 2008-07-06 13:18:30.000000000 -0700
@@ -76,6 +76,7 @@
static void remove_escape(char *name);
static bool append_file_to_dir(THD *thd, const char **filename_ptr,
const char *table_name);
+static bool test_if_data_home_dir(const char *dir);
static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
const char *any_db="*any*"; // Special symbol for check_access
@@ -2890,6 +2891,20 @@
#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,
create_table->table_name) ||
@@ -7664,3 +7679,50 @@
return TRUE;
}
+
+
+/*
+ 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[PATH_MAX+1], real_path[PATH_MAX+1];
+ 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));
+ if (!realpath(path, real_path))
+ DBUG_RETURN(1);
+ dir_len= unpack_dirname(conv_path, real_path);
+
+ 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);
+}
+
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.alioth.debian.org/pipermail/pkg-mysql-maint/attachments/20080707/4936b637/attachment.pgp
More information about the pkg-mysql-maint
mailing list