merge_role_db_privileges() was remembering pointers into Dynamic_array
acl_dbs, and later was using them, while pushing more elements into the
array. But pushing can cause realloc, and it can invalidate all pointers.
Fix: remember and use indexes of elements, not pointers.
We do not accept:
1. We did not have this problem (fixed earlier and better)
d982e717ab Bug#27510150: MYSQLDUMP FAILS FOR SPECIFIC --WHERE CLAUSES
2. We do not have such options (an DBUG_ASSERT put just in case)
bbc2e37fe4 Bug#27759871: BACKRONYM ISSUE IS STILL IN MYSQL 5.7
3. Serg fixed it in other way in this release:
e48d775c6f Bug#27980823: HEAP OVERFLOW VULNERABILITIES IN MYSQL CLIENT LIBRARY
SHOW_ROUTINE_GRANTS
Description :- Server crashes in show_routine_grants().
Analysis :- When "grant_reload_procs_priv" encounters
an error, the grant structures (structures with column,
function and procedure privileges) are freed. Server
crashes when trying to access these structures later.
Fix :- Grant structures are retained even when
"grant_reload_procs_priv()" encounters an error while
reloading column, function and procedure privileges.
INSERT PRIVILEGES FOR MYSQL.USER TABLE
Description:- Incorrect granting of EXECUTE and ALTER
ROUTINE privileges when the 'automatic_sp_privileges'
variable is set.
Fix:- EXECUTE and ALTER ROUTINE privileges are correctly
granted to the creator of the procedure when the
'automatic_sp_privileges' is SET.
A suggestion to make role propagation simpler from serg@mariadb.org.
Instead of gathering the leaf roles in an array, which for very wide
graphs could potentially mean a big part of the whole roles schema, keep
the previous logic. When finally merging a role, set its counter
to something positive.
This will effectively mean that a role has been merged, thus a random pass
through roles hash that touches a previously merged role won't cause the problem
described in MDEV-12366 any more, as propagate_role_grants_action will stop
attempting to merge from that role.
Whenever we call merge_role_privileges on a role, we make use of
the role->counter variable to check if all it's children have had their
privileges merged. Only if all children have had their privileges merged,
do we update the privileges on parent. This is done to prevent extra work.
The same idea is employed during flush privileges. You only begin merging
from "leaf" roles. The recursive calls will merge their parents at some point.
A problem arises when we try to "re-merge" a parent. Take the following graph:
{noformat}
A (0) ---- C (2) ---- D (2) ---- USER
/ /
B (0) ----/ /
/
E (0) --------------/
{noformat}
In parentheses we have the "counter" value right before we start to iterate
through the roles hash and propagate values. It represents the number of roles
granted to the current role. The order in which we iterate through the roles
hash is alphabetical.
* First merge A, which leads to decreasing the counter for C to 1. Since C is
not 0, we don't proceed with merging into C.
* Second we merge B, which leads to decreasing the counter for C to 0. Now
we proceed with merging into C. This leads to reducing the counter for D to 1
as part of C merge process.
* Third as we iterate through the hash, we see that C has counter 0, thus we
start the merge process *again*. This leads to reducing the counter for
D to 0! We then attempt to merge D.
* Fourth we start merging E. When E sees D as it's parent (according to the code)
it attempts to reduce D's counter, which leads to overflow. Now D's counter is
a very large number, thus E's privileges are not forwarded to D yet.
To correct this behavior we must make sure to only start merging from initial
leaf nodes.
When granting a role to another role, DB privileges get propagated. If
the grantee had no previous DB privileges, an extra ACL_DB entry is created to
house those "indirectly received" privileges. If, afterwards, DB
privileges are granted to the grantee directly, we must make sure to not
create a duplicate ACL_DB entry.
IS DROPPED
ANALYSIS:
=========
It is advised not to tamper with the system tables.
When primary key is dropped from a system table, certain
operations on the table which tries to access the table key
information may lead to server exit.
FIX:
====
An appropriate error is now reported in such a case.
During show create procedure we ommited to check the current role, if it
is the actual definer of the procedure. In addition, we should support
indirectly granted roles to the current role. Implemented a recursive
lookup to search the tree of grants if the rolename is present.
SQL Standard 2016, Part 5 Section 53 View I_S.ROUTINES selects
ROUTINE_BODY and its WHERE clause says that the GRANTEE must be
either PUBLIC, or CURRENT_USER or in the ENABLED_ROLES.
Also, implement MDEV-11027 a little differently from 5.5 and 10.0:
recv_apply_hashed_log_recs(): Change the return type back to void
(DB_SUCCESS was always returned).
Report progress also via systemd using sd_notifyf().
use update_hostname() to update the hostname.
test case comes from
commit 0abdeed1d6d
Author: gopal.shankar@oracle.com <>
Date: Thu Mar 29 00:20:54 2012 +0530
Bug#12766319 - 61865: RENAME USER DOES NOT WORK CORRECTLY -
REQUIRES FLUSH PRIVILEGES
Due to the collation used on the roles_mapping_hash, key comparison
would work in a case-insensitive manner. This is incorrect from the
roles mapping perspective. Make use of a case-sensitive collation for that hash,
the same one used for the acl_roles hash.
The bug is apparent when the username is longer than the rolename.
It is caused by a simple typo that caused a memcmp call to compare a
different number of bytes than necessary.
The fix was proposed by Igor Pashev. I have reviewed it and it is the
correct approach. Test case introduced by me, using the details provided
in the MDEV.
Signed-off-by: Vicențiu Ciorbaru <vicentiu@mariadb.org>