Bug#480292: CVE-2008-2079: mysql allows local users to bypass certain privilege checks

2008-07-07 Thread Devin Carraway
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
#! /bin/sh /usr/share/dpatch/dpatch-run
## 97_SECURITY_CVE-2008-2079.dpatch by  [EMAIL PROTECTED]
##
## 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.0 
-0700
+++ mysql-dfsg-5.0-5.0.32/sql/mysql_priv.h  2008-07-06 13:13:21.0 
-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.cc2006-12-20 03:14:10.0 
-0800
+++ mysql-dfsg-5.0-5.0.32/sql/mysqld.cc 2008-07-06 13:13:21.0 -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.0 
-0700
+++ mysql-dfsg-5.0-5.0.32/sql/sql_parse.cc  2008-07-06 13:18:30.0 
-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_lenconverted 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= 

Bug#480292: CVE-2008-2079: mysql allows local users to bypass certain privilege checks

2008-07-06 Thread Devin Carraway
On Fri, Jul 04, 2008 at 02:56:00PM +0200, Tomas Hoger wrote:
 Looks like upstream patch is incomplete.  Have you already notified
 upstream about the problem?

Not yet -- I still need to hand verify it against a pristine upstream; it's
reproducible with 5.0.51a from Sid, but the implementation of the path check
has changed significantly from the original patch.  I'll look into that once I
get a workable fix out for etch.


  In terms of exploitability, this allows any user with permissions to
  create tables in a db the ability to read from, write to and delete
  tables from any other database within the same mysql instance.
 
 Can you possibly explain this a little closer?  MySQL should not allow
 you to overwrite existing tables via DATA/INDEX DIRECTORY directives.
 So you can only get access to tables created in the future, if you can
 predict their names.  Or have you managed to escalate privileges to
 already existing tables using this flaw?

Sorry, I was taking the temporal part of the attack as read -- yes, the attack
is still based on creating the hostile tables before the victim database does.

-- 
Devin  \ aqua(at)devin.com, IRC:Requiem; http://www.devin.com
Carraway \ 1024D/E9ABFCD2: 13E7 199E DD1E 65F0 8905 2E43 5395 CA0D E9AB FCD2


signature.asc
Description: Digital signature


Bug#480292: CVE-2008-2079: mysql allows local users to bypass certain privilege checks

2008-07-04 Thread Tomas Hoger
Hi Devin!

Looks like upstream patch is incomplete.  Have you already notified
upstream about the problem?

 In terms of exploitability, this allows any user with permissions to
 create tables in a db the ability to read from, write to and delete
 tables from any other database within the same mysql instance.

Can you possibly explain this a little closer?  MySQL should not allow
you to overwrite existing tables via DATA/INDEX DIRECTORY directives.
So you can only get access to tables created in the future, if you can
predict their names.  Or have you managed to escalate privileges to
already existing tables using this flaw?

Thanks!

-- 
Tomas Hoger



-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]



Bug#480292: CVE-2008-2079: mysql allows local users to bypass certain privilege checks

2008-07-03 Thread Devin Carraway
reopen 480292
quit

I don't believe that the patch applied to address this bug was sufficient.  In
preparing the stable update I initially applied it, before finding two things:

First, fn_format() only calls readlink() once on the entire path, not on any
component thereof; hence it will only actually detect when the last component
of a path was a symlink.  Exploiting this merely requires adding another path
component below the symlink path -- for example:

$ ls -l /tmp/foo
lrwxrwxrwx 1 aqua 1000 14 Jul  3 05:36 /tmp/foo - /var/lib/mysql

mysql use test1 ;
Database changed

mysql create table t (a int) data directory '/tmp/foo' ;
ERROR 1210 (HY000): Incorrect arguments to DATA DIRECORY

mysql create table t (a int) data directory '/tmp/foo/mysql' ;
Query OK, 0 rows affected (0.02 sec)

$ ls -l /var/lib/mysql/mysql/t.MYD 
-rw-rw 1 mysql mysql 0 Jul  3 07:27 /var/lib/mysql/mysql/t.MYD

Second, even if fn_format() did fully resolve symlinks in the path, its output
is actually ignored; this is an except from 92_SECURITY_CVE-2008-2079.dpatch
in mysql-dfsg-5.0 5.0.51a-9:

+static bool test_if_data_home_dir(const char *dir)
+{
[...]
+  (void) fn_format(path, dir, , ,
+   (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
+  dir_len= unpack_dirname(conv_path, dir);
[...]
+else if (!memcmp(conv_path, mysql_unpacked_real_data_home, 
home_dir_len))
+  DBUG_RETURN(1);

fn_format reads the potentially hostile 'dir' and writes the marginally
readlink()'ed result to 'path'.  But unpack_dirname is passed 'dir' again, not
'path', so it's the origianl string which is used in the subsequent
comparison.

In terms of exploitability, this allows any user with permissions to create
tables in a db the ability to read from, write to and delete tables from any
other database within the same mysql instance.


-- 
Devin  \ aqua(at)devin.com, IRC:Requiem; http://www.devin.com
Carraway \ 1024D/E9ABFCD2: 13E7 199E DD1E 65F0 8905 2E43 5395 CA0D E9AB FCD2


signature.asc
Description: Digital signature


Bug#480292: CVE-2008-2079: mysql allows local users to bypass certain privilege checks

2008-05-09 Thread Steffen Joeris
Package: mysql-server-5.0
Severity: grave
Tags: security
Justification: user security hole

Hi

The following CVE(0) has been issued against mysql.

CVE-2008-2079:

MySQL 4.1.x before 4.1.24, 5.0.x before 5.0.60, 5.1.x before 5.1.24, and
6.0.x before 6.0.5 allows local users to bypass certain privilege checks
by calling CREATE TABLE on a MyISAM table with modified (1) DATA
DIRECTORY or (2) INDEX DIRECTORY arguments that are within the MySQL
home data directory, which can point to tables that are created in the
future.

Please mention the CVE id in your changelog, if you fix the issue by an
upload.

The mysql bugreport can be found here(1).


Cheers
Steffen

(0): http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-2079

(1): http://bugs.mysql.com/bug.php?id=32167



-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]