Description of problem:
Security Fix: Replication: It was possible when using statement-based replication to subvert the MySQL privilege system on a slave with a higher server release version number than that of the master by using version-specific comments in statements run on the master.
A more detailed explanation follows:
In MySQL, a version-specific comment is an SQL comment of the form /*!nnnnn sql */ where nnnnn represents a MySQL release version number and sql represents a string of SQL, or a portion of a string of SQL, that should be executed by the MySQL Server only if the server version is at least version n.nn. (For additional information and an example, see Section 8.6, “Comment Syntax”.)
In MySQL replication, the slave SQL thread executes with the SUPER privilege, regardless of the privileges with which statements are originally executed on the master. Specific to this issue, when using statement-based replication it was possible, when the slave was of a higher MySQL version than the master, to run statements that would have failed on the master due to insufficient privileges, except that these statements were wrapped in version-specific comments where the encoded version was greater than the MySQL server version of the master. However, if the MySQL release version of the slave was equal to or greater than the version encoded in the comment, the same statements could execute on this slave whose MySQL release version was less than the version number used in the comment.
Suppose that a master running MySQL 5.1.48 replicated to a slave running MySQL 4.1.49, and that a user user1 had privileges to run UPDATE statements on database db1 but no privileges at all on the mysql system database, so that the first of the following two statements succeeded, but the second statement failed, and thus the first statement was written to the binary log, but the second statement was not:
UPDATE db1.tb1 SET db1.tbl1.col1=2;
UPDATE mysql.user SET mysql.user.Super_priv='Y'
However, the text of the second statement could be wrapped in version-specific comments and thus “hidden” within the text of the first statement so that this new version of the first statement succeeded, and was written in its entireity to the binary log. The new statement containing the necessary portions of the statement affecting the “mysql.user” table wrapped within version-specific comments is shown here:
UPDATE db1.tbl1 /*!514900 ,mysql.user */
SET db1.tbl1.col1=2 /*!514900 ,mysql.user.Super_priv='Y'
Thus, a 5.1.48 master would see this statement as identical to the first of the original two statements shown previously (UPDATE db1.tb1 SET db1.tbl1.col1=2). However, the version-specific comments within the statement just shown, when run on the MySQL 5.1.49 slave, were ignored; thus the slave SQL thread would execute the statement, as shown here, with the SUPER privilege, on the slave:
To fix this issue, the ! (exclamation) character is now stripped from comments prior to statements containing them being applied on replication slaves; thus, version-specific comments that are not applied on the master are treated as normal comments on the slave and also not applied there. (Bug#49124)
Version-Release number of selected component (if applicable):
Steps to Reproduce:
1. see above
Created attachment 538013 [details]
patch without a regression test used by upstream
This is a patch which was applied by upstream in mysql-5.0.93. I've tested it and it fixes the issue described.
However, the regression test that is also a part of the upstream fix is not included in this patch. The reason is that the regression test has been developed for a bit newer version of mysql, that we have in RHEL-5, and many changes would have to be done to get the test working.
The upstream fix for this should be included in our recent security update:
although this bug is not listed there since it is not a security issue.