[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