List:Commits« Previous MessageNext Message »
From:Alexander Nozdrin Date:August 24 2006 2:29pm
Subject:bk commit into 5.0 tree (anozdrin:1.2238) BUG#16899
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of alik. When alik 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, 2006-08-24 16:29:24+04:00, anozdrin@alik. +13 -0
  Fix for BUG#16899: Possible buffer overflow in handling of DEFINER-clause
      
  User name (host name) has limit on length. The server code relies on these
  limits when storing the names. The problem was that sometimes these limits
  were not checked properly, so that could lead to buffer overflow.
    
  The fix is to check length of user/host name in parser and if string is too
  long, throw an error.

  mysql-test/r/grant.result@stripped, 2006-08-24 16:29:21+04:00, anozdrin@alik. +24 -0
    Updated result file.

  mysql-test/r/sp.result@stripped, 2006-08-24 16:29:21+04:00, anozdrin@alik. +13 -0
    Updated result file.

  mysql-test/r/trigger.result@stripped, 2006-08-24 16:29:21+04:00, anozdrin@alik. +13 -0
    Updated result file.

  mysql-test/r/view.result@stripped, 2006-08-24 16:29:21+04:00, anozdrin@alik. +11 -0
    Updated result file.

  mysql-test/t/grant.test@stripped, 2006-08-24 16:29:21+04:00, anozdrin@alik. +49 -0
    Added test for BUG#16899.

  mysql-test/t/sp.test@stripped, 2006-08-24 16:29:21+04:00, anozdrin@alik. +26 -0
    Added test for BUG#16899.

  mysql-test/t/trigger.test@stripped, 2006-08-24 16:29:21+04:00, anozdrin@alik. +30 -0
    Added test for BUG#16899.

  mysql-test/t/view.test@stripped, 2006-08-24 16:29:21+04:00, anozdrin@alik. +27 -0
    Added test for BUG#16899.

  sql/mysql_priv.h@stripped, 2006-08-24 16:29:21+04:00, anozdrin@alik. +1 -0
    Added prototype for new function.

  sql/share/errmsg.txt@stripped, 2006-08-24 16:29:22+04:00, anozdrin@alik. +6 -0
    Added new resources.

  sql/sql_acl.cc@stripped, 2006-08-24 16:29:21+04:00, anozdrin@alik. +2 -33
    Remove outdated checks.

  sql/sql_parse.cc@stripped, 2006-08-24 16:29:21+04:00, anozdrin@alik. +26 -0
    Add a new function for checking string length.

  sql/sql_yacc.yy@stripped, 2006-08-24 16:29:22+04:00, anozdrin@alik. +10 -8
    Check length of user/host name.

# 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:	anozdrin
# Host:	alik.
# Root:	/mnt/raid/alik/MySQL/devel/5.0-rel-bug16899

--- 1.396/sql/mysql_priv.h	2006-08-24 16:29:29 +04:00
+++ 1.397/sql/mysql_priv.h	2006-08-24 16:29:29 +04:00
@@ -537,6 +537,7 @@ int append_query_string(CHARSET_INFO *cs
 void get_default_definer(THD *thd, LEX_USER *definer);
 LEX_USER *create_default_definer(THD *thd);
 LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name);
+bool check_string_length(LEX_STRING *str, const char *err_msg, uint max_length);
 
 enum enum_mysql_completiontype {
   ROLLBACK_RELEASE=-2, ROLLBACK=1,  ROLLBACK_AND_CHAIN=7,

--- 1.197/sql/sql_acl.cc	2006-08-24 16:29:29 +04:00
+++ 1.198/sql/sql_acl.cc	2006-08-24 16:29:29 +04:00
@@ -2895,14 +2895,7 @@ bool mysql_table_grant(THD *thd, TABLE_L
   {
     int error;
     GRANT_TABLE *grant_table;
-    if (Str->host.length > HOSTNAME_LENGTH ||
-	Str->user.length > USERNAME_LENGTH)
-    {
-      my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER),
-                 MYF(0));
-      result= TRUE;
-      continue;
-    }
+
     /* Create user if needed */
     error=replace_user_table(thd, tables[0].table, *Str,
 			     0, revoke_grant, create_new_users,
@@ -3102,15 +3095,7 @@ bool mysql_routine_grant(THD *thd, TABLE
   {
     int error;
     GRANT_NAME *grant_name;
-    if (Str->host.length > HOSTNAME_LENGTH ||
-	Str->user.length > USERNAME_LENGTH)
-    {
-      if (!no_error)
-	my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER),
-                   MYF(0));
-      result= TRUE;
-      continue;
-    }
+
     /* Create user if needed */
     error=replace_user_table(thd, tables[0].table, *Str,
 			     0, revoke_grant, create_new_users,
@@ -3231,14 +3216,6 @@ bool mysql_grant(THD *thd, const char *d
   int result=0;
   while ((Str = str_list++))
   {
-    if (Str->host.length > HOSTNAME_LENGTH ||
-	Str->user.length > USERNAME_LENGTH)
-    {
-      my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER),
-                 MYF(0));
-      result= -1;
-      continue;
-    }
     if (replace_user_table(thd, tables[0].table, *Str,
                            (!db ? rights : 0), revoke_grant, create_new_users,
                            test(thd->variables.sql_mode &
@@ -4126,14 +4103,6 @@ bool mysql_show_grants(THD *thd,LEX_USER
   if (!initialized)
   {
     my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables");
-    DBUG_RETURN(TRUE);
-  }
-
-  if (lex_user->host.length > HOSTNAME_LENGTH ||
-      lex_user->user.length > USERNAME_LENGTH)
-  {
-    my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER),
-               MYF(0));
     DBUG_RETURN(TRUE);
   }
 

--- 1.557/sql/sql_parse.cc	2006-08-24 16:29:29 +04:00
+++ 1.558/sql/sql_parse.cc	2006-08-24 16:29:29 +04:00
@@ -7499,3 +7499,29 @@ LEX_USER *create_definer(THD *thd, LEX_S
 
   return definer;
 }
+
+
+/*
+  Check that length of a string does not exceed some limit.
+
+  SYNOPSIS
+    check_string_length()
+      str         string to be checked
+      err_msg     error message to be displayed if the string is too long
+      max_length  max length
+
+  RETURN
+    FALSE   the passed string is not longer than max_length
+    TRUE    the passed string is longer than max_length
+*/
+
+bool check_string_length(LEX_STRING *str, const char *err_msg,
+                         uint max_length)
+{
+  if (str->length <= max_length)
+    return FALSE;
+
+  my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_length);
+
+  return TRUE;
+}

--- 1.472/sql/sql_yacc.yy	2006-08-24 16:29:29 +04:00
+++ 1.473/sql/sql_yacc.yy	2006-08-24 16:29:29 +04:00
@@ -7479,6 +7479,9 @@ user:
 	  $$->user = $1;
 	  $$->host.str= (char *) "%";
 	  $$->host.length= 1;
+
+	  if (check_string_length(&$$->user, ER(ER_USERNAME), USERNAME_LENGTH))
+	    YYABORT;
 	}
 	| ident_or_text '@' ident_or_text
 	  {
@@ -7486,6 +7489,11 @@ user:
 	    if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
 	      YYABORT;
 	    $$->user = $1; $$->host=$3;
+
+	    if (check_string_length(&$$->user, ER(ER_USERNAME), USERNAME_LENGTH) ||
+	        check_string_length(&$$->host, ER(ER_HOSTNAME),
+					       HOSTNAME_LENGTH))
+	      YYABORT;
 	  }
 	| CURRENT_USER optional_braces
 	{
@@ -8966,15 +8974,9 @@ definer:
            */
           YYTHD->lex->definer= 0;
 	}
-	| DEFINER_SYM EQ CURRENT_USER optional_braces
+	| DEFINER_SYM EQ user
 	{
-          if (! (YYTHD->lex->definer= create_default_definer(YYTHD)))
-            YYABORT;
-	}
-	| DEFINER_SYM EQ ident_or_text '@' ident_or_text
-	{
-          if (!(YYTHD->lex->definer= create_definer(YYTHD, &$3, &$5)))
-            YYABORT;
+          YYTHD->lex->definer= $3;
 	}
 	;
 

--- 1.65/sql/share/errmsg.txt	2006-08-24 16:29:29 +04:00
+++ 1.66/sql/share/errmsg.txt	2006-08-24 16:29:29 +04:00
@@ -5621,3 +5621,9 @@ ER_TABLE_CANT_HANDLE_SPKEYS
         eng "The used table type doesn't support SPATIAL indexes"
 ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA
 	eng "Triggers can not be created on system tables"
+ER_USERNAME
+	eng "user name"
+ER_HOSTNAME
+	eng "host name"
+ER_WRONG_STRING_LENGTH
+	eng "String '%-.70s' is too long for %s (should be no longer than %d)"

--- 1.162/mysql-test/r/view.result	2006-08-24 16:29:29 +04:00
+++ 1.163/mysql-test/r/view.result	2006-08-24 16:29:29 +04:00
@@ -2736,3 +2736,14 @@ m	e
 1	b
 DROP VIEW v1;
 DROP TABLE IF EXISTS t1,t2;
+DROP TABLE IF EXISTS t1;
+DROP VIEW IF EXISTS v1;
+DROP VIEW IF EXISTS v2;
+CREATE TABLE t1(a INT, b INT);
+CREATE DEFINER=1234567890abcdefGHIKL@localhost
+VIEW v1 AS SELECT a FROM t1;
+ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no
longer than 16)
+CREATE
DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY
+VIEW v2 AS SELECT b FROM t1;
+ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY'
is too long for host name (should be no longer than 60)
+DROP TABLE t1;

--- 1.147/mysql-test/t/view.test	2006-08-24 16:29:29 +04:00
+++ 1.148/mysql-test/t/view.test	2006-08-24 16:29:29 +04:00
@@ -2596,3 +2596,30 @@ SELECT * FROM t2;
 
 DROP VIEW v1;
 DROP TABLE IF EXISTS t1,t2;
+
+
+#
+# Test for BUG#16899: Possible buffer overflow in handling of DEFINER-clause.
+#
+
+# Prepare.
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP VIEW IF EXISTS v1;
+DROP VIEW IF EXISTS v2;
+--enable_warnings
+
+CREATE TABLE t1(a INT, b INT);
+
+--error ER_WRONG_STRING_LENGTH
+CREATE DEFINER=1234567890abcdefGHIKL@localhost
+  VIEW v1 AS SELECT a FROM t1;
+
+--error ER_WRONG_STRING_LENGTH
+CREATE
DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY
+  VIEW v2 AS SELECT b FROM t1;
+
+# Cleanup.
+
+DROP TABLE t1;

--- 1.42/mysql-test/r/trigger.result	2006-08-24 16:29:29 +04:00
+++ 1.43/mysql-test/r/trigger.result	2006-08-24 16:29:29 +04:00
@@ -1089,4 +1089,17 @@ begin
 set @a:= 1;
 end|
 ERROR HY000: Triggers can not be created on system tables
+use test|
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+CREATE TABLE t1(c INT);
+CREATE TABLE t2(c INT);
+CREATE DEFINER=1234567890abcdefGHIKL@localhost
+TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1;
+ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no
longer than 16)
+CREATE
DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY
+TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW SET @a = 2;
+ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY'
is too long for host name (should be no longer than 60)
+DROP TABLE t1;
+DROP TABLE t2;
 End of 5.0 tests

--- 1.47/mysql-test/t/trigger.test	2006-08-24 16:29:29 +04:00
+++ 1.48/mysql-test/t/trigger.test	2006-08-24 16:29:29 +04:00
@@ -1301,6 +1301,36 @@ create trigger wont_work after update on
 begin
  set @a:= 1;
 end|
+use test|
 delimiter ;|
+
+
+#
+# Test for BUG#16899: Possible buffer overflow in handling of DEFINER-clause.
+#
+
+# Prepare.
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+--enable_warnings
+
+CREATE TABLE t1(c INT);
+CREATE TABLE t2(c INT);
+
+--error ER_WRONG_STRING_LENGTH
+CREATE DEFINER=1234567890abcdefGHIKL@localhost
+  TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1;
+
+--error ER_WRONG_STRING_LENGTH
+CREATE
DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY
+  TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW SET @a = 2;
+
+# Cleanup.
+
+DROP TABLE t1;
+DROP TABLE t2;
+
 
 --echo End of 5.0 tests

--- 1.52/mysql-test/r/grant.result	2006-08-24 16:29:29 +04:00
+++ 1.53/mysql-test/r/grant.result	2006-08-24 16:29:29 +04:00
@@ -867,3 +867,27 @@ insert into mysql.user select * from t2;
 flush privileges;
 drop table t2;
 drop table t1;
+GRANT CREATE ON mysqltest.* TO 1234567890abcdefGHIKL@localhost;
+ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no
longer than 16)
+GRANT CREATE ON mysqltest.* TO
some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY'
is too long for host name (should be no longer than 60)
+REVOKE CREATE ON mysqltest.* FROM 1234567890abcdefGHIKL@localhost;
+ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no
longer than 16)
+REVOKE CREATE ON mysqltest.* FROM
some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY'
is too long for host name (should be no longer than 60)
+GRANT CREATE ON t1 TO 1234567890abcdefGHIKL@localhost;
+ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no
longer than 16)
+GRANT CREATE ON t1 TO
some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY'
is too long for host name (should be no longer than 60)
+REVOKE CREATE ON t1 FROM 1234567890abcdefGHIKL@localhost;
+ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no
longer than 16)
+REVOKE CREATE ON t1 FROM
some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY'
is too long for host name (should be no longer than 60)
+GRANT EXECUTE ON PROCEDURE p1 TO 1234567890abcdefGHIKL@localhost;
+ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no
longer than 16)
+GRANT EXECUTE ON PROCEDURE p1 TO
some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY'
is too long for host name (should be no longer than 60)
+REVOKE EXECUTE ON PROCEDURE p1 FROM 1234567890abcdefGHIKL@localhost;
+ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no
longer than 16)
+REVOKE EXECUTE ON PROCEDURE t1 FROM
some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY'
is too long for host name (should be no longer than 60)

--- 1.41/mysql-test/t/grant.test	2006-08-24 16:29:29 +04:00
+++ 1.42/mysql-test/t/grant.test	2006-08-24 16:29:29 +04:00
@@ -681,3 +681,52 @@ drop table t2;
 drop table t1;
 
 
+#
+# Test for BUG#16899: Possible buffer overflow in handling of DEFINER-clause.
+#
+# These checks are intended to ensure that appropriate errors are risen when
+# illegal user name or hostname is specified in user-clause of GRANT/REVOKE
+# statements.
+#
+
+# Working with database-level privileges.
+
+--error ER_WRONG_STRING_LENGTH
+GRANT CREATE ON mysqltest.* TO 1234567890abcdefGHIKL@localhost;
+
+--error ER_WRONG_STRING_LENGTH
+GRANT CREATE ON mysqltest.* TO
some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+
+--error ER_WRONG_STRING_LENGTH
+REVOKE CREATE ON mysqltest.* FROM 1234567890abcdefGHIKL@localhost;
+
+--error ER_WRONG_STRING_LENGTH
+REVOKE CREATE ON mysqltest.* FROM
some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+
+# Working with table-level privileges.
+
+--error ER_WRONG_STRING_LENGTH
+GRANT CREATE ON t1 TO 1234567890abcdefGHIKL@localhost;
+
+--error ER_WRONG_STRING_LENGTH
+GRANT CREATE ON t1 TO
some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+
+--error ER_WRONG_STRING_LENGTH
+REVOKE CREATE ON t1 FROM 1234567890abcdefGHIKL@localhost;
+
+--error ER_WRONG_STRING_LENGTH
+REVOKE CREATE ON t1 FROM
some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+
+# Working with routine-level privileges.
+
+--error ER_WRONG_STRING_LENGTH
+GRANT EXECUTE ON PROCEDURE p1 TO 1234567890abcdefGHIKL@localhost;
+
+--error ER_WRONG_STRING_LENGTH
+GRANT EXECUTE ON PROCEDURE p1 TO
some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+
+--error ER_WRONG_STRING_LENGTH
+REVOKE EXECUTE ON PROCEDURE p1 FROM 1234567890abcdefGHIKL@localhost;
+
+--error ER_WRONG_STRING_LENGTH
+REVOKE EXECUTE ON PROCEDURE t1 FROM
some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;

--- 1.203/mysql-test/r/sp.result	2006-08-24 16:29:29 +04:00
+++ 1.204/mysql-test/r/sp.result	2006-08-24 16:29:29 +04:00
@@ -5072,4 +5072,17 @@ a
 1
 use test|
 drop table t3|
+DROP PROCEDURE IF EXISTS bug16899_p1|
+DROP FUNCTION IF EXISTS bug16899_f1|
+CREATE DEFINER=1234567890abcdefGHIKL@localhost PROCEDURE bug16899_p1()
+BEGIN
+SET @a = 1;
+END|
+ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no
longer than 16)
+CREATE
DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY
+FUNCTION bug16899_f1() RETURNS INT
+BEGIN
+RETURN 1;
+END|
+ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY'
is too long for host name (should be no longer than 60)
 drop table t1,t2;

--- 1.191/mysql-test/t/sp.test	2006-08-24 16:29:29 +04:00
+++ 1.192/mysql-test/t/sp.test	2006-08-24 16:29:29 +04:00
@@ -5987,6 +5987,32 @@ select * from (select 1 as a) as t1 natu
 use test|
 drop table t3|
 
+
+#
+# Test for BUG#16899: Possible buffer overflow in handling of DEFINER-clause.
+#
+
+# Prepare.
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS bug16899_p1|
+DROP FUNCTION IF EXISTS bug16899_f1|
+--enable_warnings
+
+--error ER_WRONG_STRING_LENGTH
+CREATE DEFINER=1234567890abcdefGHIKL@localhost PROCEDURE bug16899_p1()
+BEGIN
+  SET @a = 1;
+END|
+
+--error ER_WRONG_STRING_LENGTH
+CREATE
DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY
+  FUNCTION bug16899_f1() RETURNS INT
+BEGIN
+  RETURN 1;
+END|
+
+
 #
 # BUG#NNNN: New bug synopsis
 #
Thread
bk commit into 5.0 tree (anozdrin:1.2238) BUG#16899Alexander Nozdrin24 Aug