Bug #51277 SUPER_ACL should be checked unconditionaly (binlog_format and binlog_direct)
Submitted: 18 Feb 2010 9:30 Modified: 27 Apr 2010 17:12
Reporter: Alfranio Correia Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Replication Severity:S3 (Non-critical)
Version:5.1, 5.5+ OS:Any
Assigned to: Alfranio Correia CPU Architecture:Any
Tags: binlog_format, Options
Triage: Triaged: D3 (Medium)

[18 Feb 2010 9:30] Alfranio Correia
Description:
SUPER_ACL privileges should be always checked unconditionally.

How to repeat:
Check both binlog_direct_check and binlog_format_check.

For example,

static bool binlog_direct_check(sys_var *self, THD *thd, set_var *var)
{
   /*
     Makes the session variable 'binlog_direct_non_transactional_updates'
     read-only inside a transaction.
   */
   if (thd->active_transaction() && (var->type == OPT_SESSION))
   {
     my_error(ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT, MYF(0));
     return 1;
   }
   /*
     Makes the session variable 'binlog_direct_non_transactional_updates'
     read-only if within a procedure, trigger or function.
   */
   if (thd->in_sub_stmt)
   {
     my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT, MYF(0));
     return 1;
   }

  if (check_has_super(self, thd, var))
    return true;
  if (var->type == OPT_GLOBAL ||
      (thd->variables.binlog_direct_non_trans_update ==
       static_cast<my_bool>(var->save_result.ulonglong_value)))
    return false;

  return false;
}

Suggested fix:
For example,

static bool binlog_direct_check(sys_var *self, THD *thd, set_var *var)
 {
-   /*
-     Makes the session variable 'binlog_direct_non_transactional_updates'
-     read-only inside a transaction.
-   */
-   if (thd->active_transaction() && (var->type == OPT_SESSION))
-   {
-     my_error(ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT, MYF(0));
-     return 1;
-   }
+  if (check_has_super(self, thd, var))
+    return true;
+
+  if (var->type == OPT_GLOBAL ||
+      (thd->variables.binlog_direct_non_trans_update ==
+       static_cast<my_bool>(var->save_result.ulonglong_value)))
+    return false;
+
    /*
      Makes the session variable 'binlog_direct_non_transactional_updates'
      read-only if within a procedure, trigger or function.
@@ -327,15 +327,17 @@
    if (thd->in_sub_stmt)
    {
      my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT, MYF(0));
-     return 1;
-   }
-
-  if (check_has_super(self, thd, var))
-    return true;
-  if (var->type == OPT_GLOBAL ||
-      (thd->variables.binlog_direct_non_trans_update ==
-       static_cast<my_bool>(var->save_result.ulonglong_value)))
-    return false;
+     return true;
+   }
+   /*
+     Makes the session variable 'binlog_direct_non_transactional_updates'
+     read-only inside a transaction.
+   */
+   if (thd->active_transaction())
+   {
+     my_error(ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT, MYF(0));
+     return true;
+   }

   return false;
 }
[18 Feb 2010 14:17] 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/100758

2968 Alfranio Correia	2010-02-18
      BUG#51277 SUPER_ACL should be checked unconditionaly (binlog_format and binlog_direct)
      
      SUPER_ACL should be checked unconditionally while verifying if the binlog_format
      or the binlog_direct_non_transactional_updates might be changed.
      
      Roughly speaking, both session values cannot be changed in the context of a
      transaction or a stored function. Note that changing the global values does
      not cause any effect until a new connection is created.
      
      So, we fixed the problem by first checking the permissions and the scope ((i.e.
      global or session). In this patch, we also re-structure the test case to
      make it more readable.
[19 Feb 2010 12:43] 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/100856

2970 Alfranio Correia	2010-02-19
      BUG#51277 SUPER_ACL should be checked unconditionally (binlog_format and binlog_direct)
      
      SUPER_ACL should be checked unconditionally while verifying if the binlog_format
      or the binlog_direct_non_transactional_updates might be changed.
      
      Roughly speaking, both session values cannot be changed in the context of a
      transaction or a stored function. Note that changing the global values does
      not cause any effect until a new connection is created.
      
      So, we fixed the problem by first checking the permissions and then if the
      value we're changing into is the same as the previous value or if the variable
      has global scope. In either case (i.e. values are the same or global scope),
      we do nothing (don't even report an error).
      
      In this patch, we also re-structure the test case to make it more readable.
[24 Feb 2010 12:46] 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/101316

2970 Alfranio Correia	2010-02-24
      BUG#51277 SUPER_ACL should be checked unconditionally (binlog_format and binlog_direct)
      
      SUPER_ACL should be checked unconditionally while verifying if the binlog_format
      or the binlog_direct_non_transactional_updates might be changed.
      
      Roughly speaking, both session values cannot be changed in the context of a
      transaction or a stored function. Note that changing the global value does
      not cause any effect until a new connection is created.
      
      So, we fixed the problem by first checking the permissions and right after further
      verifications are ignored if the global value is being updated. In this patch, we
      also re-structure the test case to make it more readable.
[27 Apr 2010 9:46] Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20100427094135-5s49ecp3ckson6e2) (version source revid:alik@sun.com-20100427093843-uekr85qkd7orx12t) (merge vers: 6.0.14-alpha) (pib:16)
[27 Apr 2010 9:49] Bugs System
Pushed into 5.5.5-m3 (revid:alik@sun.com-20100427093804-a2k3rrjpwu5jegu8) (version source revid:alik@sun.com-20100427093804-a2k3rrjpwu5jegu8) (merge vers: 5.5.5-m3) (pib:16)
[27 Apr 2010 9:52] Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20100427094036-38frbg3famdlvjup) (version source revid:alik@sun.com-20100427093825-92wc8b22d4yg34ju) (pib:16)
[27 Apr 2010 17:12] Jon Stephens
Documented in the 5.5.5 and 6.0.14 changelogs as follows:

        When changing binlog_format or
        binlog_direct_non_transactional_updates, permissions were not
        checked prior to checking the scope and context of the variable
        being changed.

        As a result of this fix, an error is no longer reported when --
        in the context of a transaction or a stored function -- you try 
        to set a value for a session variable that is the same as its 
        previous value, or for a variable whose scope is global only.

Closed.