This merges the patch series that fixes a lot of missing validation
checks for read_log_event(). The merge includes a few added fixes that
are needed in new code introduced in 13.1.
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
This merges the patch series that fixes a lot of missing validation
checks for read_log_event(). The merge includes a few added fixes that
are needed in new code introduced in 12.3.
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
REVOKE DENY .. FROM PUBLIC needs table-level UPDATE privilege for
mysql.global_priv. Tighten the privilege check, which also accepted
column-level UPDATE, because check_grant() defers the column check.
Assisted-by: Claude:claude-sonnet-5-5
OpenSSL 3 escapes '/' and '+' in X509_NAME_oneline() output; OpenSSL 1.1
and WolfSSL don't. A REQUIRE ISSUER/SUBJECT grant from one library can
stop matching after switching to another.
Default comparison stays strcmp(). old_mode=X509_LENIENT_COMPARE opts
into falling back to an escape-aware compare, applied to whichever side
the currently-linked library's own escaping affects, at the cost of
reopening the ambiguity a crafted certificate could exploit to
impersonate another identity.
Adds regression tests against a real certificate with an ambiguous CN
Assisted-by: Claude Sonnet 5 <noreply@anthropic.com>
Defer the host-privileged/host-blocked check for a PROXY-header-derived
address until after the client's SSL handshake completes, instead of
sending it immediately in clear text.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
DENY ... TO PUBLIC denies everyone, including whoever tries to revoke
it, via the "deny wins" merge at every scope (global, db, table, column,
routine). Allow REVOKE DENY ... FROM PUBLIC when the revoker can UPDATE
mysql.global_priv (same as hand-editing).
Assisted-by: Claude:claude-5-sonnet
The "is it my own thread" check compared the login user name
(Security_context::user) and ignored the host, so u1@localhost could see
and kill threads of u1@'127.0.0.1'.
Compare the authenticated account instead:
* all comparisons are done in sctx->is_priv_user() now
* change user_matches() to priv_user_matches(), which uses is_priv_user()
* use it in KILL, KILL USER, SHOW PROCESSLIST, I_S.PROCESSLIST,
COM_PROCESS_INFO and SHOW EXPLAIN/ANALYZE FOR.
* all the remaining places use is_priv_user() directly instead
of doing strcmp: SHOW GRANTS, SHOW CREATE PROCEDURE, I_S.VIEWS,
the DEFINER clause, optimizer trace and change_security_context().
Assisted-by: Claude:claude-5-opus
In propagate_role_grants_action() (called by grant_reload() on startup
and FLUSH PRIVILEGES), role privilege merging uses a counter-based
bottom-up ordering: each role's counter tracks how many of its granted
sub-roles still need to be processed, and merge_role_privileges() merges
a role only once its counter reaches zero.
The bug: when an intermediate role such as org_role_1 (which inherits
only from a USAGE-only app_role_1) was merged with no privilege changes,
merge_role_privileges() returned 1 as an optimisation to stop upward
traversal. This prevented the traversal from ever reaching user_role_1
to decrement its counter. A second leaf traversal (from app_role_2)
could decrement user_role_1's counter only once, leaving it at 1
instead of 0, so user_role_1 was never merged and had no effective
privileges.
The "stop if nothing changed" optimisation is valid for incremental
propagate_role_grants() calls (after a single GRANT/REVOKE), where
every ancestor was already correctly merged. It is not valid for the
full-reload case, where the counters must be decremented by every leaf
traversal to guarantee correct bottom-up ordering.
Fix: add an initial_load flag to PRIVS_TO_MERGE. When set (only in
propagate_role_grants_action), the early-stop optimisation is disabled
so traversals always visit all ancestors.
Assisted-By: Claude:claude-4.6-sonnet
a90779098b changed the
interface to the json_valid to take a json_engine_t
so that it could be interupted and so that warnings
could become visible.
On merge from that 10.11 to 11.4 it was discovered
that the ColumnStore engine uses this interface.
Restored the original json_valid function exactly
how ColumnStore expects this and added renamed
the function with json_engine_t to be json_valid_engine.
This follows the same convention as in the commit
756fc6fd9a that was
for json_normalize, that ColumnStore also used.
a90779098b changed the
interface to the json_valid to take a json_engine_t
so that it could be interupted and so that warnings
could become visible.
On merge from that 10.11 to 11.4 it was discovered
that the ColumnStore engine uses this interface.
Restored the original json_valid function exactly
how ColumnStore expects this and added renamed
the function with json_engine_t to be json_valid_engine.
This follows the same convention as in the commit
756fc6fd9a that was
for json_normalize, that ColumnStore also used.
Or max_statement_time limit.
Change the json_valid to take a json_engine_t argument.
Adjust the Item_json_valid to have a json_engine_t and
to report an error.
Note this means that invalid json syntax now has a
note on any json error. Raising this to a warning can
cause check constraints of JSON_VALID() to result
in ER_JSON_SYNTAX rather than ER_CONSTRAINT_FAILED
(valided in main.type_json test).
Consequential changes in debug build to json acl
testing validation and unit test having a dummy json_engine_t.
json_normalize also uses the same engine that was
passed as its argument to test json_valid. Because
the character set may have changed, if there's an error
adjust the je->s.c_str pointer. Its only the offset that
is currently used in the error messages anyway so there
may be offset errors depending on the original character
set.
The database name in GRANT is stored in mysql.db.Db, which holds 64
characters. Escaping '_' or '%' with a backslash to match them literally
can make the stored name longer than 64 characters, and it was silently
truncated into a non-functional grant. Reject it with ER_WRONG_DB_NAME
instead, the same error CREATE DATABASE gives for an over-long name.
Add support for CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA in COM_CHANGE_USER
packet parsing, allowing passwords >= 251 bytes.
Changes:
- Server: parse_com_change_user_packet() now handles LENENC-encoded
password length when CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA is set
- Server: fix db pointer calculation for old protocol without
CLIENT_SECURE_CONNECTION (need +1 to skip null terminator)
- Add regression test for COM_CHANGE_USER with long passwords
Note: This fix requires a corresponding client-side fix in libmariadb's
send_change_user_packet() to send LENENC-encoded passwords.
Document that the packet buffer is null-terminated by the network layer,
ensuring strend(user) remains within bounds and passwd stays within
the packet.
Remove the unscoped #pragma GCC diagnostic ignored
"-Wdeprecated-declarations" from include/violite.h and replace all
sprintf/vsprintf calls with snprintf/vsnprintf across the codebase.
Where possible, pass actual buffer sizes as function parameters
instead of using hardcoded constants or recomputing strlen().
Notable API changes:
- get_date(): added to_len parameter for buffer size
- nice_time(), end_timer() in client/mysql.cc: added buff_size
- generate_new_name(): added name_size parameter
- calc_md5(): added buffer_size parameter (fixes off-by-one)
- MD5_HASH_TO_STRING macro: added _size parameter
- Added MYSQL_UDF_MAX_RESULT_LENGTH constant in mysql_com.h
Also fixed a pre-existing bug in sql/rpl_mi.cc where the ellipsis
"..." was written to the wrong buffer (dbuff instead of buff).
Vendored code is excluded: extra/readline, extra/wolfssl,
wsrep-lib, libmariadb, storage/mroonga/vendor, zlib.