Details
-
Bug
-
Status: Closed (View Workflow)
-
Critical
-
Resolution: Duplicate
-
10.6, 10.11, 11.4, 11.8, 12.3, 13.0, 13.1
-
Not for Release Notes
Description
Update: ref below for a more generic all-versions-affected GRANT based testcase, i.e. not using the new 13.1 DENY
A multi-user DENY where one target does not exist is applied to the valid user on the primary but is not written to the binary log, so a replica keeps the access the primary just removed. u1 is granted SELECT on test, then DENY SELECT ON test.* TO u1, u2 runs where u2 does not exist. The primary denies u1 - a SELECT there is refused with ER_TABLEACCESS_DENIED_ERROR - but the statement errors overall on the missing u2, so it is not binlogged. After sync_slave_with_master the same SELECT by u1 on the replica returns the row.
--source include/master-slave.inc
|
connection master; |
CREATE TABLE test.t (a INT); |
INSERT INTO test.t VALUES (1); |
CREATE USER u1@'%' IDENTIFIED BY 'pw'; |
GRANT SELECT ON test.* TO u1@'%'; |
sync_slave_with_master;
|
connection master; |
SET SESSION sql_mode='NO_AUTO_CREATE_USER'; |
--error ER_PASSWORD_NO_MATCH
|
DENY SELECT ON test.* TO u1@'%', u2@'%'; |
connect (m,127.0.0.1,u1,pw,,$MASTER_MYPORT); |
--error ER_TABLEACCESS_DENIED_ERROR,ER_DBACCESS_DENIED_ERROR
|
SELECT * FROM test.t; |
connection master; |
sync_slave_with_master;
|
connection slave; |
connect (s,127.0.0.1,u1,pw,,$SLAVE_MYPORT); |
--error ER_TABLEACCESS_DENIED_ERROR,ER_DBACCESS_DENIED_ERROR
|
SELECT * FROM test.t; |
connection master; |
DROP USER u1@'%'; |
DROP TABLE test.t; |
--source include/rpl_end.inc |
Leads to:
|
MDEV-14443 CS 13.1.0 0c709a5fe3db1733493c3b84bef9e4bc62555c17 (Optimized, Clang 22.1.8-20260622) Build 07/07/2026 |
mysqltest: At line 20: query 'SELECT * FROM test.t' succeeded - should have failed with error ER_TABLEACCESS_DENIED_ERROR (1142)...
|
DENY reuses the GRANT path, which binlogs only on full success (if (!result) write_bin_log(...) in mysql_grant / mysql_table_grant). For GRANT a stranded statement leaves the replica less privileged, which is safe; for DENY the safe direction is inverted, so the replica ends up more privileged than the primary. This is separate from MDEV-40025 - there the DENY is never applied (most-specific matching row wins, by design); here it is applied and enforced on the primary and only fails to replicate. Reproduces for binlog_format stmt, row and mix.
Perhaps applying a multi-user DENY atomically (validate the whole list first, apply nothing on any failure), or binlogging it whenever at least one deny was applied so replicas match, could be viable paths forward.
 |
Attachments
Issue Links
- duplicates
-
MDEV-29848 Partially failed grant not written into binlog => discrepancy between master and replica
-
- Confirmed
-
- relates to
-
MDEV-29848 Partially failed grant not written into binlog => discrepancy between master and replica
-
- Confirmed
-