Bug #44658 Create procedure makes server crash when user does not have ALL privilege
Submitted: 5 May 2009 8:21 Modified: 3 Aug 2009 23:25
Reporter: Jørgen Løland Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Security: Privileges Severity:S1 (Critical)
Version:5.1, 6.0-BZR OS:Any
Assigned to: Kristofer Pettersson CPU Architecture:Any

[5 May 2009 8:21] Jørgen Løland
Description:
MySQL crashes if a user without ALL privileges attempts to create a procedure. In an attempt to grant just the necessary privileges, the user was granted the CREATE ROUTINE privilege.

How to repeat:
mtr test script file:

CREATE USER limited_priv;
GRANT CREATE ON proccrash.* TO 'limited_priv'@'%';
GRANT CREATE ROUTINE ON proccrash.* TO 'limited_priv'@'%';
#uncomment grant all to make crash go away
#GRANT ALL ON *.* TO 'limited_priv'@'%';
FLUSH PRIVILEGES;

CONNECT (con_limited_priv,localhost,limited_priv,,);

CREATE DATABASE proccrash;
DELIMITER ||;
CREATE PROCEDURE proccrash.dorepeat(p1 INT)
 BEGIN
 SET @x = 0;
 REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
 END ;||
DELIMITER ;||

Suggested fix:
Either fail with an error message (if CREATE PROCEDURE is not sufficient to create procedures) or let the user create the procedure.
[5 May 2009 8:41] Sveta Smirnova
Bug is repeatable with 5.1 as well.
[19 May 2009 16:10] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/74493

2874 Kristofer Pettersson	2009-05-19
      Bug#44658 Create procedure makes server crash when user does not have ALL privilege
      
      MySQL crashes if a user without proper privileges attempts to create a procedure.
      
      Since the current user lacks the right to assign the ALTER and EXECUTE ROUTINE
      privileges an error is thrown by the grant subsystem. This error sets the SQLSTATE,
      but the error state is not interrupting execution since it isn't considered fatal in this
      context. Instead an attempt is made to push another SQLSTATE to the Diagnostic area and
      this causes an assertion and the server stops.
      
      The patch back ports a stack implementation of the internal error handler interface. This
      enables the use of multiple error handlers so that it is possible to intercept and cancel
      errors thrown by lower layers. 
     @ mysql-test/r/grant.result
        * Test case for bug44658
     @ mysql-test/t/grant.test
        * Test case for bug44658
     @ sql/sql_acl.cc
        * sp_grant_routine is only called from the SQLCOM_CREATE_PROCEDURE execution path and in this
          context it is not a fatal error to fail to assign the automatic privileges ALTER and EXECUTE
          ROUTINE. To avoid that other errors are thrown a dummy error handler is used to cancel them out.
     @ sql/sql_class.cc
        * Back ported error handler implementation
     @ sql/sql_class.h
        * Back ported error handler implementation
        * Introduced dummy error handler for cancelling all errors.
[22 May 2009 15:38] Kristofer Pettersson
There is a possibility that the process of automatically assigning grants never should fail because of "invalid permissions". Thus we have two issues with this bug:
1. Entangled exception tree which causes multiple SQL states to be set.
   This can be solved:
 a) Error handler which reduces the number of possible states after a funciton call to something manageable (Try-catch )
 b) Untangle the exception tree by tracing all execution paths.
2. An error in the privilege check for automatic grants.
[26 May 2009 14:59] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/74966

2874 Kristofer Pettersson	2009-05-26
      Bug#44658 Create procedure makes server crash when user does not have ALL privilege
      
      MySQL crashes if a user without proper privileges attempts to create a procedure.
      
      If the current user has a host mask then a new user will need to be created for the
      assignment of ALTER and EXECUTE ROUTINE privileges. Since it isn't allowed to
      implicity create anonymous user accounts with no password an error is thrown by the
      grant subsystem. This error sets the SQLSTATE and when the execution stack later
      unravels an attempt is made to push another SQLSTATE to the Diagnostic
      area and this causes an assertion and the server stops.
      
      Implicit assignment of privileges is assumed to be a non-critical operation and thus
      should not emit any errors, only warnings.
      
      The patch back ports a stack implementation of the internal error handler interface.
      This enables the use of multiple error handlers so that it is possible to intercept
      and cancel errors thrown by lower layers.
     @ mysql-test/r/grant.result
        test case for bug 44658
     @ mysql-test/t/grant.test
        test case for bug 44658
     @ sql/sql_acl.cc
        * Introduced dummy error handling for cancelling all errors emitted from mysql_routine_grant.
        This is done because sp_grant_privilege is assumed to be a non-critical operation and thus
        shouldn't cause any critical errors (only warnings).
     @ sql/sql_class.cc
        Back ported error handing implementation from 6.0 branch.
     @ sql/sql_class.h
        Back ported error handing implementation from 6.0 branch.
[28 May 2009 10:36] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/75131

2874 Kristofer Pettersson	2009-05-28
      Bug#44658 Create procedure makes server crash when user does not have ALL privilege
      
      MySQL crashes if a user without proper privileges attempts to create a procedure.
      
      The crash happens because more than one error state is pushed onto the Diagnostic
      area. In this particular case the user is denied to implicitly create a new user
      account with the implicitly granted privileges ALTER- and EXECUTE ROUTINE.
      
      The new account is needed if the original user account contained a host mask.
      A user account with a host mask is a distinct user account in this context.
      An alternative would be to first get the most permissive user account which
      include the current user connection and then assign privileges to that
      account. This behavior change is considered out of scope for this bug patch.
      
      The implicit assignment of privileges when a user creates a stored routine is a
      considered to be a feature for user convenience and as such it is not
      a critical operation. Any failure to complete this operation is thus considered
      non-fatal (an error becomes a warning).
       
      The patch back ports a stack implementation of the internal error handler interface.
      This enables the use of multiple error handlers so that it is possible to intercept and
      cancel errors thrown by lower layers. 
     @ mysql-test/r/grant.result
        * Added test case for bug44658
     @ mysql-test/t/grant.test
        * Added test case for bug44658
     @ sql/sql_acl.cc
        * Removed the non functional no_error parameter from the function prototype.
        The function is called from two places and in one of the places we now 
        ignore errors through error handlers.
        * Introduced an error handler to cancel any error state from mysql_routine_grant.
        * Moved my_ok() signal from mysql_routine_grant to make it easier to avoid
        setting the wrong state in the Diagnostic area.
     @ sql/sql_acl.h
        * Removed the non functional no_error parameter from the function prototype.
        The function is called from two places and in one of the places we now 
        ignore errors through error handlers.
     @ sql/sql_class.cc
        * Back ported implementation of internal error handler from 6.0 branch
     @ sql/sql_class.h
        * Back ported implementation of internal error handler from 6.0 branch
     @ sql/sql_parse.cc
        * Moved my_ok() signal from mysql_routine grant to make it easier to avoid
        setting the wrong state in the Diagnostic area.
[28 May 2009 14:32] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/75159

2874 Kristofer Pettersson	2009-05-28
      Bug#44658 Create procedure makes server crash when user does not have ALL privilege
      
      MySQL crashes if a user without proper privileges attempts to create a procedure.
      
      The crash happens because more than one error state is pushed onto the Diagnostic
      area. In this particular case the user is denied to implicitly create a new user
      account with the implicitly granted privileges ALTER- and EXECUTE ROUTINE.
      
      The new account is needed if the original user account contained a host mask.
      A user account with a host mask is a distinct user account in this context.
      An alternative would be to first get the most permissive user account which
      include the current user connection and then assign privileges to that
      account. This behavior change is considered out of scope for this bug patch.
      
      The implicit assignment of privileges when a user creates a stored routine is a
      considered to be a feature for user convenience and as such it is not
      a critical operation. Any failure to complete this operation is thus considered
      non-fatal (an error becomes a warning).
      
      The patch back ports a stack implementation of the internal error handler interface.
      This enables the use of multiple error handlers so that it is possible to intercept
      and cancel errors thrown by lower layers. This is needed as a error handler already
      is used in the call stack emitting the errors which needs to be converted.
     @ mysql-test/r/grant.result
        * Added test case for bug44658
     @ mysql-test/t/grant.test
        * Added test case for bug44658
     @ sql/sp.cc
        * Removed non functional paramter no_error and my_error calls as all errors
          from this function will be converted to a warning anyway.
     @ sql/sp.h
        * Removed non functional paramter no_error and my_error calls as all errors
          from this function will be converted to a warning anyway.
     @ sql/sql_acl.cc
        * Removed the non functional no_error parameter from the function prototype.
          The function is called from two places and in one of the places we now 
          ignore errors through error handlers.
        * Introduced the parameter write_to_binlog
        * Introduced an error handler to cancel any error state from mysql_routine_grant.
        * Moved my_ok() signal from mysql_routine_grant to make it easier to avoid
          setting the wrong state in the Diagnostic area.
     @ sql/sql_acl.h
        * Removed the non functional no_error parameter from the function prototype.
          The function is called from two places and in one of the places we now 
          ignore errors through error handlers.
        * Introduced the parameter write_to_binlog
     @ sql/sql_class.cc
        * Back ported implementation of internal error handler from 6.0 branch
     @ sql/sql_class.h
        * Back ported implementation of internal error handler from 6.0 branch
     @ sql/sql_parse.cc
        * Moved my_ok() signal from mysql_routine grant to make it easier to avoid
          setting the wrong state in the Diagnostic area.
[28 May 2009 20:40] Konstantin Osipov
Sent the review by email, letting Davi change the bug status when he feels the patch is 100% complete.
[29 May 2009 12:54] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/75238

2874 Kristofer Pettersson	2009-05-29
      Bug#44658 Create procedure makes server crash when user does not have ALL privilege
      
      MySQL crashes if a user without proper privileges attempts to create a procedure.
      
      The crash happens because more than one error state is pushed onto the Diagnostic
      area. In this particular case the user is denied to implicitly create a new user
      account with the implicitly granted privileges ALTER- and EXECUTE ROUTINE.
      
      The new account is needed if the original user account contained a host mask.
      A user account with a host mask is a distinct user account in this context.
      An alternative would be to first get the most permissive user account which
      include the current user connection and then assign privileges to that
      account. This behavior change is considered out of scope for this bug patch.
      
      The implicit assignment of privileges when a user creates a stored routine is a
      considered to be a feature for user convenience and as such it is not
      a critical operation. Any failure to complete this operation is thus considered
      non-fatal (an error becomes a warning).
      
      The patch back ports a stack implementation of the internal error handler interface.
      This enables the use of multiple error handlers so that it is possible to intercept
      and cancel errors thrown by lower layers. This is needed as a error handler already
      is used in the call stack emitting the errors which needs to be converted.
     @ mysql-test/r/grant.result
        * Added test case for bug44658
     @ mysql-test/t/grant.test
        * Added test case for bug44658
     @ sql/sp.cc
        * Removed non functional paramter no_error and my_error calls as all errors
          from this function will be converted to a warning anyway.
        * Change function return type from int to bool.
     @ sql/sp.h
        * Removed non functional paramter no_error and my_error calls as all errors
          from this function will be converted to a warning anyway.
        * Changed function return value from int to bool
     @ sql/sql_acl.cc
        * Removed the non functional no_error parameter from the function prototype.
          The function is called from two places and in one of the places we now 
          ignore errors through error handlers.
        * Introduced the parameter write_to_binlog
        * Introduced an error handler to cancel any error state from mysql_routine_grant.
        * Moved my_ok() signal from mysql_routine_grant to make it easier to avoid
          setting the wrong state in the Diagnostic area.
        * Changed the broken error state in sp_grant_privileges() to a warning
          so that if "CREATE PROCEDURE" fails because "Password hash isn't a hexidecimal number"
          it is still clear what happened.
     @ sql/sql_acl.h
        * Removed the non functional no_error parameter from the function prototype.
          The function is called from two places and in one of the places we now 
          ignore errors through error handlers.
        * Introduced the parameter write_to_binlog
        * Changed return type for sp_grant_privileges() from int to bool
     @ sql/sql_class.cc
        * Back ported implementation of internal error handler from 6.0 branch
     @ sql/sql_class.h
        * Back ported implementation of internal error handler from 6.0 branch
     @ sql/sql_parse.cc
        * Moved my_ok() signal from mysql_routine_grant() to make it easier to avoid
          setting the wrong state in the Diagnostic area.
[29 May 2009 13:41] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/75247

2874 Kristofer Pettersson	2009-05-29
      Bug#44658 Create procedure makes server crash when user does not have ALL privilege
      
      MySQL crashes if a user without proper privileges attempts to create a procedure.
      
      The crash happens because more than one error state is pushed onto the Diagnostic
      area. In this particular case the user is denied to implicitly create a new user
      account with the implicitly granted privileges ALTER- and EXECUTE ROUTINE.
      
      The new account is needed if the original user account contained a host mask.
      A user account with a host mask is a distinct user account in this context.
      An alternative would be to first get the most permissive user account which
      include the current user connection and then assign privileges to that
      account. This behavior change is considered out of scope for this bug patch.
      
      The implicit assignment of privileges when a user creates a stored routine is a
      considered to be a feature for user convenience and as such it is not
      a critical operation. Any failure to complete this operation is thus considered
      non-fatal (an error becomes a warning).
      
      The patch back ports a stack implementation of the internal error handler interface.
      This enables the use of multiple error handlers so that it is possible to intercept
      and cancel errors thrown by lower layers. This is needed as a error handler already
      is used in the call stack emitting the errors which needs to be converted.
     @ mysql-test/r/grant.result
        * Added test case for bug44658
     @ mysql-test/t/grant.test
        * Added test case for bug44658
     @ sql/sp.cc
        * Removed non functional parameter no_error and my_error calls as all errors
          from this function will be converted to a warning anyway.
        * Change function return type from int to bool.
     @ sql/sp.h
        * Removed non functional parameter no_error and my_error calls as all errors
          from this function will be converted to a warning anyway.
        * Changed function return value from int to bool
     @ sql/sql_acl.cc
        * Removed the non functional no_error parameter from the function prototype.
          The function is called from two places and in one of the places we now 
          ignore errors through error handlers.
        * Introduced the parameter write_to_binlog
        * Introduced an error handler to cancel any error state from mysql_routine_grant.
        * Moved my_ok() signal from mysql_routine_grant to make it easier to avoid
          setting the wrong state in the Diagnostic area.
        * Changed the broken error state in sp_grant_privileges() to a warning
          so that if "CREATE PROCEDURE" fails because "Password hash isn't a hexidecimal
          number" it is still clear what happened.
     @ sql/sql_acl.h
        * Removed the non functional no_error parameter from the function prototype.
          The function is called from two places and in one of the places we now 
          ignore errors through error handlers.
        * Introduced the parameter write_to_binlog
        * Changed return type for sp_grant_privileges() from int to bool
     @ sql/sql_class.cc
        * Back ported implementation of internal error handler from 6.0 branch
     @ sql/sql_class.h
        * Back ported implementation of internal error handler from 6.0 branch
     @ sql/sql_parse.cc
        * Moved my_ok() signal from mysql_routine_grant() to make it easier to avoid
          setting the wrong state in the Diagnostic area.
[16 Jun 2009 11:03] Bugs System
Pushed into 5.1.36 (revid:joro@sun.com-20090616102155-3zhezogudt4uxdyn) (version source revid:azundris@mysql.com-20090529164935-xe3dceff53d7pywb) (merge vers: 5.1.36) (pib:6)
[17 Jun 2009 19:25] Bugs System
Pushed into 5.4.4-alpha (revid:alik@sun.com-20090616183122-chjzbaa30qopdra9) (version source revid:azundris@mysql.com-20090529170733-wxq9j0idmss9rllz) (merge vers: 6.0.12-alpha) (pib:11)
[3 Aug 2009 23:25] Paul Dubois
Noted in 5.1.36, 5.4.4 changelogs.

The server crashed if an account without the proper privileges
attempted to create a stored procedure.
[12 Aug 2009 21:48] Paul Dubois
Noted in 5.4.2 changelog because next 5.4 version will be 5.4.2 and not 5.4.4.
[14 Aug 2009 22:46] Paul Dubois
Ignore previous comment about 5.4.2.
[26 Aug 2009 13:45] Bugs System
Pushed into 5.1.37-ndb-7.0.8 (revid:jonas@mysql.com-20090826132541-yablppc59e3yb54l) (version source revid:jonas@mysql.com-20090826132541-yablppc59e3yb54l) (merge vers: 5.1.37-ndb-7.0.8) (pib:11)
[26 Aug 2009 13:46] Bugs System
Pushed into 5.1.37-ndb-6.3.27 (revid:jonas@mysql.com-20090826105955-bkj027t47gfbamnc) (version source revid:jonas@mysql.com-20090826105955-bkj027t47gfbamnc) (merge vers: 5.1.37-ndb-6.3.27) (pib:11)
[26 Aug 2009 13:48] Bugs System
Pushed into 5.1.37-ndb-6.2.19 (revid:jonas@mysql.com-20090825194404-37rtosk049t9koc4) (version source revid:jonas@mysql.com-20090825194404-37rtosk049t9koc4) (merge vers: 5.1.37-ndb-6.2.19) (pib:11)
[27 Aug 2009 16:32] Bugs System
Pushed into 5.1.35-ndb-7.1.0 (revid:magnus.blaudd@sun.com-20090827163030-6o3kk6r2oua159hr) (version source revid:jonas@mysql.com-20090826132541-yablppc59e3yb54l) (merge vers: 5.1.37-ndb-7.0.8) (pib:11)
[16 Jan 2010 0:36] Paul Dubois
Noted in 5.5.0 changelog.