From 06da82383be087565e389bd79aa7ea00542ea286 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 19 Nov 2025 10:44:05 +0200 Subject: [PATCH 1/6] MDEV-38126: Remove dead code for MySQL 5.7 and old MariaDB The release of MySQL 5.7.44 (the last one in the 5.7 series) took place in August 2023. Also, the release of MariaDB 5.5.68 (the last one in the 5.5 series) took place in May 2020. Let us remove some dead code that is related to these, as well as attempts to detect the server version by symbol lookup. The audit plugin will typically be built and distributed together with the current MariaDB server version. --- plugin/server_audit/CMakeLists.txt | 2 +- plugin/server_audit/plugin_audit_v4.h | 561 -------------------------- plugin/server_audit/server_audit.c | 416 ++----------------- plugin/server_audit/test_audit_v4.c | 163 -------- 4 files changed, 30 insertions(+), 1112 deletions(-) delete mode 100644 plugin/server_audit/plugin_audit_v4.h delete mode 100644 plugin/server_audit/test_audit_v4.c diff --git a/plugin/server_audit/CMakeLists.txt b/plugin/server_audit/CMakeLists.txt index 8a5333cfb9fe3..a30f431b92e5e 100644 --- a/plugin/server_audit/CMakeLists.txt +++ b/plugin/server_audit/CMakeLists.txt @@ -13,6 +13,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA -SET(SOURCES server_audit.c test_audit_v4.c plugin_audit_v4.h) +SET(SOURCES server_audit.c) MYSQL_ADD_PLUGIN(server_audit ${SOURCES} MODULE_ONLY RECOMPILE_FOR_EMBEDDED) diff --git a/plugin/server_audit/plugin_audit_v4.h b/plugin/server_audit/plugin_audit_v4.h deleted file mode 100644 index a2a38806f4f21..0000000000000 --- a/plugin/server_audit/plugin_audit_v4.h +++ /dev/null @@ -1,561 +0,0 @@ -/* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; version 2 of - the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ - -#ifndef _my_audit_h -#define _my_audit_h - -#ifndef PLUGIN_CONTEXT -#include "plugin.h" -#include "mysql/mysql_lex_string.h" -#ifndef MYSQL_ABI_CHECK -#include "m_string.h" -#endif -#include "my_command.h" -#include "my_sqlcommand.h" -#endif /*PLUGIN_CONTEXT*/ - -#define MYSQL_AUDIT_INTERFACE_VERSION 0x0401 - -/** - @enum mysql_event_class_t - - Audit event classes. -*/ -typedef enum -{ - MYSQL_AUDIT_GENERAL_CLASS = 0, - MYSQL_AUDIT_CONNECTION_CLASS = 1, - MYSQL_AUDIT_PARSE_CLASS = 2, - MYSQL_AUDIT_AUTHORIZATION_CLASS = 3, - MYSQL_AUDIT_TABLE_ACCESS_CLASS = 4, - MYSQL_AUDIT_GLOBAL_VARIABLE_CLASS = 5, - MYSQL_AUDIT_SERVER_STARTUP_CLASS = 6, - MYSQL_AUDIT_SERVER_SHUTDOWN_CLASS = 7, - MYSQL_AUDIT_COMMAND_CLASS = 8, - MYSQL_AUDIT_QUERY_CLASS = 9, - MYSQL_AUDIT_STORED_PROGRAM_CLASS = 10, - /* This item must be last in the list. */ - MYSQL_AUDIT_CLASS_MASK_SIZE -} mysql_event_class_t; - -/** - @struct st_mysql_audit - - The descriptor structure that is referred from st_mysql_plugin. -*/ -struct st_mysql_audit -{ - /** - Interface version. - */ - int interface_version; - - /** - Event occurs when the event class consumer is to be - disassociated from the specified THD.This would typically occur - before some operation which may require sleeping - such as when - waiting for the next query from the client. - */ - void (*release_thd)(MYSQL_THD); - - /** - Invoked whenever an event occurs which is of any - class for which the plugin has interest.The second argument - indicates the specific event class and the third argument is data - as required for that class. - */ - int (*event_notify)(MYSQL_THD, mysql_event_class_t, const void *); - - /** - An array of bits used to indicate what event classes - that this plugin wants to receive. - */ - unsigned long class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE]; -}; - -/** - @typedef enum_sql_command_t - - SQL command type definition. -*/ -typedef enum enum_sql_command enum_sql_command_t; - -/** - @enum mysql_event_general_subclass_t - - Events for the MYSQL_AUDIT_GENERAL_CLASS event class. -*/ -typedef enum -{ - /** occurs before emitting to the general query log. */ - MYSQL_AUDIT_GENERAL_LOG = 1 << 0, - /** occurs before transmitting errors to the user. */ - MYSQL_AUDIT_GENERAL_ERROR = 1 << 1, - /** occurs after transmitting a resultset to the user. */ - MYSQL_AUDIT_GENERAL_RESULT = 1 << 2, - /** occurs after transmitting a resultset or errors */ - MYSQL_AUDIT_GENERAL_STATUS = 1 << 3 -} mysql_event_general_subclass_t; - -#define MYSQL_AUDIT_GENERAL_ALL (MYSQL_AUDIT_GENERAL_LOG | \ - MYSQL_AUDIT_GENERAL_ERROR | \ - MYSQL_AUDIT_GENERAL_RESULT | \ - MYSQL_AUDIT_GENERAL_STATUS) -/** - @struct mysql_event_general - - Structure for the MYSQL_AUDIT_GENERAL_CLASS event class. -*/ -struct mysql_event_general -{ - mysql_event_general_subclass_t event_subclass; - int general_error_code; - unsigned long general_thread_id; - MYSQL_LEX_CSTRING general_user; - MYSQL_LEX_CSTRING general_command; - MYSQL_LEX_CSTRING general_query; - struct charset_info_st *general_charset; - unsigned long long general_time; - unsigned long long general_rows; - MYSQL_LEX_CSTRING general_host; - MYSQL_LEX_CSTRING general_sql_command; - MYSQL_LEX_CSTRING general_external_user; - MYSQL_LEX_CSTRING general_ip; -}; - -/** - @enum mysql_event_connection_subclass_t - - Events for MYSQL_AUDIT_CONNECTION_CLASS event class. -*/ -typedef enum -{ - /** occurs after authentication phase is completed. */ - MYSQL_AUDIT_CONNECTION_CONNECT = 1 << 0, - /** occurs after connection is terminated. */ - MYSQL_AUDIT_CONNECTION_DISCONNECT = 1 << 1, - /** occurs after COM_CHANGE_USER RPC is completed. */ - MYSQL_AUDIT_CONNECTION_CHANGE_USER = 1 << 2, - /** occurs before authentication. */ - MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE = 1 << 3 -} mysql_event_connection_subclass_t; - -#define MYSQL_AUDIT_CONNECTION_ALL (MYSQL_AUDIT_CONNECTION_CONNECT | \ - MYSQL_AUDIT_CONNECTION_DISCONNECT | \ - MYSQL_AUDIT_CONNECTION_CHANGE_USER | \ - MYSQL_AUDIT_CONNECTION_PRE_AUTHENTICATE) -/** - @struct mysql_event_connection - - Structure for the MYSQL_AUDIT_CONNECTION_CLASS event class. -*/ -struct mysql_event_connection -{ - /** Event subclass. */ - mysql_event_connection_subclass_t event_subclass; - /** Current status of the connection. */ - int status; - /** Connection id. */ - unsigned long connection_id; - /** User name of this connection. */ - MYSQL_LEX_CSTRING user; - /** Priv user name. */ - MYSQL_LEX_CSTRING priv_user; - /** External user name. */ - MYSQL_LEX_CSTRING external_user; - /** Proxy user used for this connection. */ - MYSQL_LEX_CSTRING proxy_user; - /** Connection host. */ - MYSQL_LEX_CSTRING host; - /** IP of the connection. */ - MYSQL_LEX_CSTRING ip; - /** Database name specified at connection time. */ - MYSQL_LEX_CSTRING database; - /** Connection type: - - 0 Undefined - - 1 TCP/IP - - 2 Socket - - 3 Named pipe - - 4 SSL - - 5 Shared memory - */ - int connection_type; -}; - -/** -@enum mysql_event_parse_subclass_t - -Events for MYSQL_AUDIT_PARSE_CLASS event class. -*/ -typedef enum -{ - /** occurs before the query parsing. */ - MYSQL_AUDIT_PARSE_PREPARSE = 1 << 0, - /** occurs after the query parsing. */ - MYSQL_AUDIT_PARSE_POSTPARSE = 1 << 1 -} mysql_event_parse_subclass_t; - -#define MYSQL_AUDIT_PARSE_ALL (MYSQL_AUDIT_PARSE_PREPARSE | \ - MYSQL_AUDIT_PARSE_POSTPARSE) - -typedef enum -{ - MYSQL_AUDIT_PARSE_REWRITE_PLUGIN_NONE = 0, - /// mysql_event_parse::flags Must be set by a plugin if the query is rewritten. - MYSQL_AUDIT_PARSE_REWRITE_PLUGIN_QUERY_REWRITTEN = 1 << 0, - /// mysql_event_parse::flags Is set by the server if the query is prepared statement. - MYSQL_AUDIT_PARSE_REWRITE_PLUGIN_IS_PREPARED_STATEMENT = 1 << 1 -} mysql_event_parse_rewrite_plugin_flag; - -/** Data for the MYSQL_AUDIT_PARSE events */ -struct mysql_event_parse -{ - /** MYSQL_AUDIT_[PRE|POST]_PARSE event id */ - mysql_event_parse_subclass_t event_subclass; - - /** one of FLAG_REWRITE_PLUGIN_* */ - mysql_event_parse_rewrite_plugin_flag *flags; - - /** input: the original query text */ - MYSQL_LEX_CSTRING query; - - /** output: returns the null-terminated rewritten query allocated by my_malloc() */ - MYSQL_LEX_CSTRING *rewritten_query; -}; - -/** - @enum mysql_event_authorization_subclass_t - - Events for MYSQL_AUDIT_AUTHORIZATION_CLASS event class. -*/ -typedef enum -{ - MYSQL_AUDIT_AUTHORIZATION_USER = 1 << 0, - /** Occurs when database privilege is checked. */ - MYSQL_AUDIT_AUTHORIZATION_DB = 1 << 1, - /** Occurs when table privilege is checked. */ - MYSQL_AUDIT_AUTHORIZATION_TABLE = 1 << 2, - /** Occurs when column privilege is checked. */ - MYSQL_AUDIT_AUTHORIZATION_COLUMN = 1 << 3, - /** Occurs when procedure privilege is checked. */ - MYSQL_AUDIT_AUTHORIZATION_PROCEDURE = 1 << 4, - /** Occurs when proxy privilege is checked. */ - MYSQL_AUDIT_AUTHORIZATION_PROXY = 1 << 5 -} mysql_event_authorization_subclass_t; - -#define MYSQL_AUDIT_AUTHORIZATION_ALL (MYSQL_AUDIT_AUTHORIZATION_USER | \ - MYSQL_AUDIT_AUTHORIZATION_DB | \ - MYSQL_AUDIT_AUTHORIZATION_TABLE | \ - MYSQL_AUDIT_AUTHORIZATION_COLUMN | \ - MYSQL_AUDIT_AUTHORIZATION_PROCEDURE | \ - MYSQL_AUDIT_AUTHORIZATION_PROXY) -/** - @struct mysql_event_authorization - - Structure for MYSQL_AUDIT_AUTHORIZATION_CLASS event class. -*/ -struct mysql_event_authorization -{ - /** Event subclass. */ - mysql_event_authorization_subclass_t event_subclass; - /** Event status. */ - int status; - /** Connection id. */ - unsigned int connection_id; - /** SQL command id. */ - enum_sql_command_t sql_command_id; - /** SQL query text. */ - MYSQL_LEX_CSTRING query; - /** SQL query charset. */ - const struct charset_info_st *query_charset; - /** Database name. */ - MYSQL_LEX_CSTRING database; - /** Table name. */ - MYSQL_LEX_CSTRING table; - /** Other name associated with the event. */ - MYSQL_LEX_CSTRING object; - /** Requested authorization privileges. */ - unsigned long requested_privilege; - /** Currently granted authorization privileges. */ - unsigned long granted_privilege; -}; - -/** - @enum mysql_event_table_row_access_subclass_t - - Events for MYSQL_AUDIT_TABLE_ACCES_CLASS event class. -*/ -typedef enum -{ - /** Occurs when table data are read. */ - MYSQL_AUDIT_TABLE_ACCESS_READ = 1 << 0, - /** Occurs when table data are inserted. */ - MYSQL_AUDIT_TABLE_ACCESS_INSERT = 1 << 1, - /** Occurs when table data are updated. */ - MYSQL_AUDIT_TABLE_ACCESS_UPDATE = 1 << 2, - /** Occurs when table data are deleted. */ - MYSQL_AUDIT_TABLE_ACCESS_DELETE = 1 << 3 -} mysql_event_table_access_subclass_t; - -#define MYSQL_AUDIT_TABLE_ACCESS_ALL (MYSQL_AUDIT_TABLE_ACCESS_READ | \ - MYSQL_AUDIT_TABLE_ACCESS_INSERT | \ - MYSQL_AUDIT_TABLE_ACCESS_UPDATE | \ - MYSQL_AUDIT_TABLE_ACCESS_DELETE) - -/** - @struct mysql_event_table_row_access - - Structure for MYSQL_AUDIT_TABLE_ACCES_CLASS event class. -*/ -struct mysql_event_table_access -{ - /** Event subclass. */ - mysql_event_table_access_subclass_t event_subclass; - /** Connection id. */ - unsigned long connection_id; - /** SQL command id. */ - enum_sql_command_t sql_command_id; - /** SQL query. */ - MYSQL_LEX_CSTRING query; - /** SQL query charset. */ - const struct charset_info_st *query_charset; - /** Database name. */ - MYSQL_LEX_CSTRING table_database; - /** Table name. */ - MYSQL_LEX_CSTRING table_name; -}; - -/** - @enum mysql_event_global_variable_subclass_t - - Events for MYSQL_AUDIT_GLOBAL_VARIABLE_CLASS event class. -*/ -typedef enum -{ - /** Occurs when global variable is retrieved. */ - MYSQL_AUDIT_GLOBAL_VARIABLE_GET = 1 << 0, - /** Occurs when global variable is set. */ - MYSQL_AUDIT_GLOBAL_VARIABLE_SET = 1 << 1 -} mysql_event_global_variable_subclass_t; - -#define MYSQL_AUDIT_GLOBAL_VARIABLE_ALL (MYSQL_AUDIT_GLOBAL_VARIABLE_GET | \ - MYSQL_AUDIT_GLOBAL_VARIABLE_SET) - -/** Events for MYSQL_AUDIT_GLOBAL_VARIABLE_CLASS event class. */ -struct mysql_event_global_variable -{ - /** Event subclass. */ - mysql_event_global_variable_subclass_t event_subclass; - /** Connection id. */ - unsigned long connection_id; - /** SQL command id. */ - enum_sql_command_t sql_command_id; - /** Variable name. */ - MYSQL_LEX_CSTRING variable_name; - /** Variable value. */ - MYSQL_LEX_CSTRING variable_value; -}; - -/** - @enum mysql_event_server_startup_subclass_t - - Events for MYSQL_AUDIT_SERVER_STARTUP_CLASS event class. -*/ -typedef enum -{ - /** Occurs after all subsystem are initialized during system start. */ - MYSQL_AUDIT_SERVER_STARTUP_STARTUP = 1 << 0 -} mysql_event_server_startup_subclass_t; - -#define MYSQL_AUDIT_SERVER_STARTUP_ALL (MYSQL_AUDIT_SERVER_STARTUP_STARTUP) - -/** - @struct mysql_event_server_startup - - Structure for MYSQL_AUDIT_SERVER_STARTUP_CLASS event class. -*/ -struct mysql_event_server_startup -{ - /** Event subclass. */ - mysql_event_server_startup_subclass_t event_subclass; - /** Command line arguments. */ - const char **argv; - /** Command line arguments count. */ - unsigned int argc; -}; - -/** - @enum mysql_event_server_shutdown_subclass_t - - Events for MYSQL_AUDIT_SERVER_SHUTDOWN_CLASS event class. -*/ -typedef enum -{ - /** Occurs when global variable is set. */ - MYSQL_AUDIT_SERVER_SHUTDOWN_SHUTDOWN = 1 << 0 -} mysql_event_server_shutdown_subclass_t; - -#define MYSQL_AUDIT_SERVER_SHUTDOWN_ALL (MYSQL_AUDIT_SERVER_SHUTDOWN_SHUTDOWN) - -/** - @enum mysql_server_shutdown_reason_t - - Server shutdown reason. -*/ -typedef enum -{ - /** User requested shut down. */ - MYSQL_AUDIT_SERVER_SHUTDOWN_REASON_SHUTDOWN, - /** The server aborts. */ - MYSQL_AUDIT_SERVER_SHUTDOWN_REASON_ABORT -} mysql_server_shutdown_reason_t; - -/** - @struct mysql_event_server_shutdown - - Structure for MYSQL_AUDIT_SERVER_SHUTDOWN_CLASS event class. -*/ -struct mysql_event_server_shutdown -{ - /** Shutdown event. */ - mysql_event_server_shutdown_subclass_t event_subclass; - /** Exit code associated with the shutdown event. */ - int exit_code; - /** Shutdown reason. */ - mysql_server_shutdown_reason_t reason; -}; - -/** - @enum mysql_event_command_subclass_t - - Events for MYSQL_AUDIT_COMMAND_CLASS event class. -*/ -typedef enum -{ - /** Command start event. */ - MYSQL_AUDIT_COMMAND_START = 1 << 0, - /** Command end event. */ - MYSQL_AUDIT_COMMAND_END = 1 << 1 -} mysql_event_command_subclass_t; - -#define MYSQL_AUDIT_COMMAND_ALL (MYSQL_AUDIT_COMMAND_START | \ - MYSQL_AUDIT_COMMAND_END) -/** - @typedef enum_server_command_t - - Server command type definition. -*/ -typedef enum enum_server_command enum_server_command_t; - -/** - @struct mysql_event_command - - Event for MYSQL_AUDIT_COMMAND_CLASS event class. - Events generated as a result of RPC command requests. -*/ -struct mysql_event_command -{ - /** Command event subclass. */ - mysql_event_command_subclass_t event_subclass; - /** Command event status. */ - int status; - /** Connection id. */ - unsigned long connection_id; - /** Command id. */ - enum_server_command_t command_id; -}; - -/** - @enum mysql_event_query_subclass_t - - Events for MYSQL_AUDIT_QUERY_CLASS event class. -*/ -typedef enum -{ - /** Query start event. */ - MYSQL_AUDIT_QUERY_START = 1 << 0, - /** Nested query start event. */ - MYSQL_AUDIT_QUERY_NESTED_START = 1 << 1, - /** Query post parse event. */ - MYSQL_AUDIT_QUERY_STATUS_END = 1 << 2, - /** Nested query status end event. */ - MYSQL_AUDIT_QUERY_NESTED_STATUS_END = 1 << 3 -} mysql_event_query_subclass_t; - -#define MYSQL_AUDIT_QUERY_ALL (MYSQL_AUDIT_QUERY_START | \ - MYSQL_AUDIT_QUERY_NESTED_START | \ - MYSQL_AUDIT_QUERY_STATUS_END | \ - MYSQL_AUDIT_QUERY_NESTED_STATUS_END) -/** - @struct mysql_event_command - - Event for MYSQL_AUDIT_COMMAND_CLASS event class. -*/ -struct mysql_event_query -{ - /** Event subclass. */ - mysql_event_query_subclass_t event_subclass; - /** Event status. */ - int status; - /** Connection id. */ - unsigned long connection_id; - /** SQL command id. */ - enum_sql_command_t sql_command_id; - /** SQL query. */ - MYSQL_LEX_CSTRING query; - /** SQL query charset. */ - const struct charset_info_st *query_charset; -}; - -/** - @enum mysql_event_stored_program_subclass_t - - Events for MYSQL_AUDIT_STORED_PROGRAM_CLASS event class. -*/ -typedef enum -{ - /** Stored program execution event. */ - MYSQL_AUDIT_STORED_PROGRAM_EXECUTE = 1 << 0 -} mysql_event_stored_program_subclass_t; - -#define MYSQL_AUDIT_STORED_PROGRAM_ALL (MYSQL_AUDIT_STORED_PROGRAM_EXECUTE) - -/** - @struct mysql_event_command - -Event for MYSQL_AUDIT_COMMAND_CLASS event class. -*/ -struct mysql_event_stored_program -{ - /** Event subclass. */ - mysql_event_stored_program_subclass_t event_subclass; - /** Connection id. */ - unsigned long connection_id; - /** SQL command id. */ - enum_sql_command_t sql_command_id; - /** SQL query text. */ - MYSQL_LEX_CSTRING query; - /** SQL query charset. */ - const struct charset_info_st *query_charset; - /** The Database the procedure is defined in. */ - MYSQL_LEX_CSTRING database; - /** Name of the stored program. */ - MYSQL_LEX_CSTRING name; - /** Stored program parameters. */ - void *parameters; -}; - -#endif diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index bfda256c83b1d..57c9ada2d51bb 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -18,8 +18,6 @@ #define PLUGIN_VERSION 0x106 #define PLUGIN_STR_VERSION "1.6.0" -#define _my_thread_var loc_thread_var - #include #include @@ -72,17 +70,6 @@ static void closelog() {} #endif /*!_WIN32*/ -/* - Defines that can be used to reshape the pluging: - #define MARIADB_ONLY - #define USE_MARIA_PLUGIN_INTERFACE -*/ - -#if !defined(MYSQL_DYNAMIC_PLUGIN) && !defined(MARIADB_ONLY) -#include -#define MARIADB_ONLY -#endif /*MYSQL_PLUGIN_DYNAMIC*/ - #include #include #include @@ -95,10 +82,6 @@ static void closelog() {} #define RTLD_DEFAULT NULL #endif -static char **int_mysql_data_home; -static char *default_home= (char *)"."; -#define mysql_data_home (*int_mysql_data_home) - #ifndef HOSTNAME_LENGTH #define HOSTNAME_LENGTH 255 #endif @@ -128,20 +111,11 @@ static char *default_home= (char *)"."; #endif /*WIN32*/ -extern MYSQL_PLUGIN_IMPORT char server_version[]; -static const char *serv_ver= NULL; const char *(*thd_priv_host_ptr)(MYSQL_THD thd, size_t *length); -static int started_mysql= 0; -static int mysql_57_started= 0; -static int debug_server_started= 0; -static int use_event_data_for_disconnect= 0; -static int started_mariadb= 0; -static int maria_55_started= 0; -static int maria_above_5= 0; static char *incl_users, *excl_users, *file_path, *syslog_info; static char path_buffer[FN_REFLEN]; -static unsigned int mode, mode_readonly= 0; +static unsigned int mode; static ulong output_type; static ulong syslog_facility, syslog_priority; @@ -400,8 +374,6 @@ static long log_write_failures= 0; static char current_log_buf[FN_REFLEN]= ""; static char last_error_buf[512]= ""; -extern void *mysql_v4_descriptor; - static struct st_mysql_show_var audit_status[]= { {"server_audit_active", (char *)&is_active, SHOW_BOOL}, @@ -422,13 +394,7 @@ static PSI_rwlock_info rwlock_key_list[]= static mysql_prlock_t lock_operations; static mysql_mutex_t lock_atomic; -/* The Percona server and partly MySQL don't support */ -/* launching client errors in the 'update_variable' methods. */ -/* So the client errors just disabled for them. */ -/* The possible solution is to implement the 'check_variable'*/ -/* methods there properly, but at the moment i'm not sure it */ -/* worths doing. */ -#define CLIENT_ERROR if (!started_mysql) my_printf_error +#define CLIENT_ERROR my_printf_error #define ADD_ATOMIC(x, a) \ do { \ @@ -1102,13 +1068,7 @@ static void setup_connection_connect(MYSQL_THD thd,struct connection_info *cn, // 5 is "'" around host and user and "@" priv_host= event->proxy_user + sizeof(char[MAX_HOSTNAME + USERNAME_LENGTH + 5]); - if (mysql_57_started) - { - priv_host+= sizeof(size_t); - priv_host_length= *(size_t *) (priv_host + MAX_HOSTNAME); - } - else - priv_host_length= strlen(priv_host); + priv_host_length= strlen(priv_host); } @@ -2028,12 +1988,8 @@ static void update_connection_info(MYSQL_THD thd, struct connection_info *cn, if (init_db_command) { /* Change DB */ - if (mysql_57_started) - get_str_n(cn->db, &cn->db_length, sizeof(cn->db), - event->database.str, event->database.length); - else - get_str_n(cn->db, &cn->db_length, sizeof(cn->db), - event->general_query, event->general_query_length); + get_str_n(cn->db, &cn->db_length, sizeof(cn->db), + event->general_query, event->general_query_length); } cn->query_id= mode ? query_counter++ : event->query_id; cn->query= event->general_query; @@ -2176,34 +2132,7 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) if (!thd || internal_stop_logging) return; - if (maria_55_started && debug_server_started && - event_class == MYSQL_AUDIT_GENERAL_CLASS) - { - /* - There's a bug in MariaDB 5.5 that prevents using thread local - variables in some cases. - The 'select * from notexisting_table;' query produces such case. - So just use the static buffer in this case. - */ - const struct mysql_event_general *event = - (const struct mysql_event_general *) ev; - - if (event->event_subclass == MYSQL_AUDIT_GENERAL_ERROR || - (event->event_subclass == MYSQL_AUDIT_GENERAL_STATUS && - event->general_query_length == 0 && - cn_error_buffer.query_id == event->query_id)) - { - cn= &cn_error_buffer; - cn->header= 1; - } - else - cn= get_loc_info(thd); - } - else - { - cn= get_loc_info(thd); - } - + cn= get_loc_info(thd); update_connection_info(thd, cn, event_class, ev, &after_action); if (!logging) @@ -2275,10 +2204,7 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) log_proxy(cn, event); break; case MYSQL_AUDIT_CONNECTION_DISCONNECT: - if (use_event_data_for_disconnect) - log_connection_event(event, "DISCONNECT"); - else - log_connection(&ci_disconnect_buffer, event, "DISCONNECT"); + log_connection_event(event, "DISCONNECT"); break; case MYSQL_AUDIT_CONNECTION_CHANGE_USER: log_connection(cn, event, "CHANGEUSER"); @@ -2328,131 +2254,6 @@ struct mysql_event_general_v8 }; -static void auditing_v8(MYSQL_THD thd, struct mysql_event_general_v8 *ev_v8) -{ -#ifdef __linux__ -#ifdef DBUG_OFF - #ifdef __x86_64__ - static const int cmd_off= 4200; - static const int db_off= 120; - static const int db_len_off= 128; - #else - static const int cmd_off= 2668; - static const int db_off= 60; - static const int db_len_off= 64; - #endif /*x86_64*/ -#else - #ifdef __x86_64__ - static const int cmd_off= 4432; - static const int db_off= 120; - static const int db_len_off= 128; - #else - static const int cmd_off= 2808; - static const int db_off= 64; - static const int db_len_off= 68; - #endif /*x86_64*/ -#endif /*DBUG_OFF*/ -#endif /* __linux__ */ - - struct mysql_event_general event; - - if (ev_v8->event_class != MYSQL_AUDIT_GENERAL_CLASS) - return; - - event.event_subclass= ev_v8->event_subclass; - event.general_error_code= ev_v8->general_error_code; - event.general_thread_id= ev_v8->general_thread_id; - event.general_user= ev_v8->general_user; - event.general_user_length= ev_v8->general_user_length; - event.general_command= ev_v8->general_command; - event.general_command_length= ev_v8->general_command_length; - event.general_query= ev_v8->general_query; - event.general_query_length= ev_v8->general_query_length; - event.general_charset= ev_v8->general_charset; - event.general_time= ev_v8->general_time; - event.general_rows= ev_v8->general_rows; - event.database.str= 0; - event.database.length= 0; - - if (event.general_query_length > 0) - { - event.event_subclass= MYSQL_AUDIT_GENERAL_STATUS; - event.general_command= "Query"; - event.general_command_length= 5; -#ifdef __linux__ - event.database.str= *(char **) (((char *) thd) + db_off); - event.database.length= *(size_t *) (((char *) thd) + db_len_off); -#endif /*__linux*/ - } -#ifdef __linux__ - else if (*((int *) (((char *)thd) + cmd_off)) == 2) - { - event.event_subclass= MYSQL_AUDIT_GENERAL_LOG; - event.general_command= "Init DB"; - event.general_command_length= 7; - event.general_query= *(char **) (((char *) thd) + db_off); - event.general_query_length= *(size_t *) (((char *) thd) + db_len_off); - } -#endif /*__linux*/ - auditing(thd, ev_v8->event_class, &event); -} - - -static void auditing_v13(MYSQL_THD thd, unsigned int *ev_v0) -{ - struct mysql_event_general event= *(const struct mysql_event_general *) (ev_v0+1); - - if (event.general_query_length > 0) - { - event.event_subclass= MYSQL_AUDIT_GENERAL_STATUS; - event.general_command= "Query"; - event.general_command_length= 5; - } - auditing(thd, ev_v0[0], &event); -} - - -int get_db_mysql57(MYSQL_THD thd, char **name, size_t *len) -{ -#ifdef __linux__ - int db_off; - int db_len_off; - if (debug_server_started) - { -#ifdef __x86_64__ - db_off= 608; - db_len_off= 616; -#elif __aarch64__ - db_off= 632; - db_len_off= 640; -#else - db_off= 0; - db_len_off= 0; -#endif /*x86_64*/ - } - else - { -#ifdef __x86_64__ - db_off= 536; - db_len_off= 544; -#elif __aarch64__ - db_off= 552; - db_len_off= 560; -#else - db_off= 0; - db_len_off= 0; -#endif /*x86_64*/ - } - - *name= *(char **) (((char *) thd) + db_off); - *len= *((size_t *) (((char*) thd) + db_len_off)); - if (*name && (*name)[*len] != 0) - return 1; - return 0; -#else - return 1; -#endif -} /* As it's just too difficult to #include "sql_class.h", let's just copy the necessary part of the system_variables @@ -2530,53 +2331,9 @@ typedef struct loc_system_variables static int init_done= 0; -static void* find_sym(const char *sym) -{ -#ifdef _WIN32 - return GetProcAddress(GetModuleHandle("server.dll"),sym); -#else - return dlsym(RTLD_DEFAULT, sym); -#endif -} - static int server_audit_init(void *p __attribute__((unused))) { - if (!serv_ver) - { - serv_ver= find_sym("server_version"); - } - - if (!mysql_57_started) - { - const void *my_hash_init_ptr= find_sym("_my_hash_init"); - if (!my_hash_init_ptr) - { - maria_above_5= 1; - my_hash_init_ptr= find_sym("my_hash_init2"); - } - if (!my_hash_init_ptr) - return 1; - - thd_priv_host_ptr= dlsym(RTLD_DEFAULT, "thd_priv_host"); - } - - if(!(int_mysql_data_home= find_sym("mysql_data_home"))) - { - if(!(int_mysql_data_home= find_sym("?mysql_data_home@@3PADA"))) - int_mysql_data_home= &default_home; - } - - if (!serv_ver) - return 1; - - if (!started_mysql) - { - if (!maria_above_5 && serv_ver[4]=='3' && serv_ver[5]<'3') - { - mode= 1; - mode_readonly= 1; - } - } + thd_priv_host_ptr= dlsym(RTLD_DEFAULT, "thd_priv_host"); if (gethostname(servhost, sizeof(servhost))) strcpy(servhost, "unknown"); @@ -2616,7 +2373,7 @@ static int server_audit_init(void *p __attribute__((unused))) /* The Query Cache shadows TABLE events if the result is taken from it */ /* so we warn users if both Query Caсhe and TABLE events enabled. */ - if (!started_mysql && FILTER(EVENT_TABLE)) + if (FILTER(EVENT_TABLE)) { ulonglong *qc_size= (ulonglong *) dlsym(RTLD_DEFAULT, "query_cache_size"); if (qc_size == NULL || *qc_size != 0) @@ -2651,15 +2408,6 @@ static int server_audit_init(void *p __attribute__((unused))) } -static int server_audit_init_mysql(void *p) -{ - started_mysql= 1; - mode= 1; - mode_readonly= 1; - return server_audit_init(p); -} - - static int server_audit_deinit(void *p __attribute__((unused))) { if (!init_done) @@ -2708,34 +2456,6 @@ static void sync_log(MYSQL_THD thd __attribute__((unused)), } -static struct st_mysql_audit mysql_descriptor = -{ - MYSQL_AUDIT_INTERFACE_VERSION, - NULL, - auditing, - { MYSQL_AUDIT_GENERAL_CLASSMASK | MYSQL_AUDIT_CONNECTION_CLASSMASK } -}; - - -mysql_declare_plugin(server_audit) -{ - MYSQL_AUDIT_PLUGIN, - &mysql_descriptor, - "SERVER_AUDIT", - " Alexey Botchkov (MariaDB Corporation)", - "Audit the server activity", - PLUGIN_LICENSE_GPL, - server_audit_init_mysql, - server_audit_deinit, - PLUGIN_VERSION, - audit_status, - vars, - NULL, - 0 -} -mysql_declare_plugin_end; - - static struct st_mysql_audit maria_descriptor = { MYSQL_AUDIT_INTERFACE_VERSION, @@ -2810,8 +2530,7 @@ static void update_file_path(MYSQL_THD thd, error_header(); fprintf(stderr, "Log file name was changed to '%s'.\n", new_name); - if (!maria_55_started || !debug_server_started) - mysql_prlock_wrlock(&lock_operations); + mysql_prlock_wrlock(&lock_operations); if (logging) log_current_query(thd); @@ -2842,8 +2561,7 @@ static void update_file_path(MYSQL_THD thd, path_buffer[sizeof(path_buffer)-1]= 0; file_path= path_buffer; exit_func: - if (!maria_55_started || !debug_server_started) - mysql_prlock_unlock(&lock_operations); + mysql_prlock_unlock(&lock_operations); ADD_ATOMIC(internal_stop_logging, -1); } @@ -2896,8 +2614,7 @@ static void update_file_buffer_size(MYSQL_THD thd __attribute__((unused)), return; ADD_ATOMIC(internal_stop_logging, 1); - if (!maria_55_started || !debug_server_started) - mysql_prlock_wrlock(&lock_operations); + mysql_prlock_wrlock(&lock_operations); if (logger_resize_buffer(logfile, file_buffer_size)) { @@ -2908,8 +2625,7 @@ static void update_file_buffer_size(MYSQL_THD thd __attribute__((unused)), MYF(ME_WARNING)); } - if (!maria_55_started || !debug_server_started) - mysql_prlock_unlock(&lock_operations); + mysql_prlock_unlock(&lock_operations); ADD_ATOMIC(internal_stop_logging, -1); } @@ -2954,8 +2670,7 @@ static void update_incl_users(MYSQL_THD thd, { char *new_users= (*(char **) save) ? *(char **) save : empty_str; size_t new_len= strlen(new_users) + 1; - if (!maria_55_started || !debug_server_started) - mysql_prlock_wrlock(&lock_operations); + mysql_prlock_wrlock(&lock_operations); mark_always_logged(thd); if (new_len > sizeof(incl_user_buffer)) @@ -2968,8 +2683,7 @@ static void update_incl_users(MYSQL_THD thd, user_coll_fill(&incl_user_coll, incl_users, &excl_user_coll, 1); error_header(); fprintf(stderr, "server_audit_incl_users set to '%s'.\n", incl_users); - if (!maria_55_started || !debug_server_started) - mysql_prlock_unlock(&lock_operations); + mysql_prlock_unlock(&lock_operations); } @@ -2979,8 +2693,7 @@ static void update_excl_users(MYSQL_THD thd __attribute__((unused)), { char *new_users= (*(char **) save) ? *(char **) save : empty_str; size_t new_len= strlen(new_users) + 1; - if (!maria_55_started || !debug_server_started) - mysql_prlock_wrlock(&lock_operations); + mysql_prlock_wrlock(&lock_operations); mark_always_logged(thd); if (new_len > sizeof(excl_user_buffer)) @@ -2993,8 +2706,7 @@ static void update_excl_users(MYSQL_THD thd __attribute__((unused)), user_coll_fill(&excl_user_coll, excl_users, &incl_user_coll, 0); error_header(); fprintf(stderr, "server_audit_excl_users set to '%s'.\n", excl_users); - if (!maria_55_started || !debug_server_started) - mysql_prlock_unlock(&lock_operations); + mysql_prlock_unlock(&lock_operations); } @@ -3071,8 +2783,7 @@ static void update_logging(MYSQL_THD thd, return; ADD_ATOMIC(internal_stop_logging, 1); - if (!maria_55_started || !debug_server_started) - mysql_prlock_wrlock(&lock_operations); + mysql_prlock_wrlock(&lock_operations); if ((logging= new_logging)) { start_logging(); @@ -3088,8 +2799,7 @@ static void update_logging(MYSQL_THD thd, stop_logging(); } - if (!maria_55_started || !debug_server_started) - mysql_prlock_unlock(&lock_operations); + mysql_prlock_unlock(&lock_operations); ADD_ATOMIC(internal_stop_logging, -1); } @@ -3099,18 +2809,16 @@ static void update_mode(MYSQL_THD thd __attribute__((unused)), void *var_ptr __attribute__((unused)), const void *save) { unsigned int new_mode= *(unsigned int *) save; - if (mode_readonly || new_mode == mode) + if (new_mode == mode) return; ADD_ATOMIC(internal_stop_logging, 1); - if (!maria_55_started || !debug_server_started) - mysql_prlock_wrlock(&lock_operations); + mysql_prlock_wrlock(&lock_operations); mark_always_logged(thd); error_header(); fprintf(stderr, "Logging mode was changed from %d to %d.\n", mode, new_mode); mode= new_mode; - if (!maria_55_started || !debug_server_started) - mysql_prlock_unlock(&lock_operations); + mysql_prlock_unlock(&lock_operations); ADD_ATOMIC(internal_stop_logging, -1); } @@ -3136,84 +2844,18 @@ static void update_syslog_ident(MYSQL_THD thd __attribute__((unused)), } -struct st_my_thread_var *loc_thread_var(void) +IF_WIN(static,__attribute__ ((constructor))) +void audit_plugin_so_init(void) { - return 0; + memset(locinfo_ini_value, 'O', sizeof(locinfo_ini_value)-1); + locinfo_ini_value[sizeof(locinfo_ini_value)-1]= 0; } - - #ifdef _WIN32 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { - if (fdwReason != DLL_PROCESS_ATTACH) - return 1; - - serv_ver= server_version; -#else -void __attribute__ ((constructor)) audit_plugin_so_init(void) -{ - serv_ver= server_version; -#endif /*_WIN32*/ - - if (!serv_ver) - goto exit; - - started_mariadb= strstr(serv_ver, "MariaDB") != 0; - debug_server_started= strstr(serv_ver, "debug") != 0; - - if (started_mariadb) - { - if (serv_ver[0] == '1') - use_event_data_for_disconnect= 1; - else - maria_55_started= 1; - } - else - { - /* Started MySQL. */ - if (serv_ver[0] == '5' && serv_ver[2] == '5') - { - int sc= serv_ver[4] - '0'; - if (serv_ver[5] >= '0' && serv_ver[5] <= '9') - sc= sc * 10 + serv_ver[5] - '0'; - if (sc <= 10) - { - mysql_descriptor.interface_version= 0x0200; - mysql_descriptor.event_notify= (void *) auditing_v8; - } - else if (sc < 14) - { - mysql_descriptor.interface_version= 0x0200; - mysql_descriptor.event_notify= (void *) auditing_v13; - } - } - else if (serv_ver[0] == '5' && serv_ver[2] == '6') - { - int sc= serv_ver[4] - '0'; - if (serv_ver[5] >= '0' && serv_ver[5] <= '9') - sc= sc * 10 + serv_ver[5] - '0'; - if (sc >= 24) - use_event_data_for_disconnect= 1; - } - else if ((serv_ver[0] == '5' && serv_ver[2] == '7') || - (serv_ver[0] == '8' && serv_ver[2] == '0')) - { - mysql_57_started= 1; - _mysql_plugin_declarations_[0].info= mysql_v4_descriptor; - use_event_data_for_disconnect= 1; - } - MYSQL_SYSVAR_NAME(loc_info).flags= PLUGIN_VAR_STR | PLUGIN_VAR_THDLOCAL | - PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC; - } - - memset(locinfo_ini_value, 'O', sizeof(locinfo_ini_value)-1); - locinfo_ini_value[sizeof(locinfo_ini_value)-1]= 0; - -exit: -#ifdef _WIN32 + if (fdwReason == DLL_PROCESS_ATTACH) + audit_plugin_so_init(); return 1; -#else - return; -#endif } +#endif diff --git a/plugin/server_audit/test_audit_v4.c b/plugin/server_audit/test_audit_v4.c deleted file mode 100644 index f37d8c7c34a83..0000000000000 --- a/plugin/server_audit/test_audit_v4.c +++ /dev/null @@ -1,163 +0,0 @@ -#define PLUGIN_CONTEXT - -/* Can't use as this includes plugin.h */ -#include - -typedef void *MYSQL_THD; -struct st_mysql_const_lex_string -{ - const char *str; - size_t length; -}; -typedef struct st_mysql_const_lex_string MYSQL_LEX_CSTRING; -enum enum_sql_command{ SQLCOM_A, SQLCOM_B }; -enum enum_server_command{ SERVCOM_A, SERVCOM_B }; - -#include "plugin_audit_v4.h" - -extern void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev); -extern int get_db_mysql57(MYSQL_THD thd, char **name, size_t *len); - - -struct mysql_event_general_302 -{ - unsigned int event_subclass; - int general_error_code; - unsigned long general_thread_id; - const char *general_user; - unsigned int general_user_length; - const char *general_command; - unsigned int general_command_length; - const char *general_query; - unsigned int general_query_length; - struct charset_info_st *general_charset; - unsigned long long general_time; - unsigned long long general_rows; - unsigned long long query_id; - char *database; - size_t database_length; -}; - - -static int auditing_v4(MYSQL_THD thd, mysql_event_class_t class, const void *ev) -{ - int *subclass= (int *)ev; - struct mysql_event_general_302 ev_302; - int subclass_v3, subclass_orig; - - if (class != MYSQL_AUDIT_GENERAL_CLASS && - class != MYSQL_AUDIT_CONNECTION_CLASS) - return 0; - - subclass_orig= *subclass; - - if (class == MYSQL_AUDIT_GENERAL_CLASS) - { - struct mysql_event_general *event= (struct mysql_event_general *) ev; - ev_302.general_error_code= event->general_error_code; - ev_302.general_thread_id= event->general_thread_id; - ev_302.general_user= event->general_user.str; - ev_302.general_user_length= (unsigned int)event->general_user.length; - ev_302.general_command= event->general_command.str; - ev_302.general_command_length= (unsigned int)event->general_command.length; - ev_302.general_query= event->general_query.str; - ev_302.general_query_length= (unsigned int)event->general_query.length; - ev_302.general_charset= event->general_charset; - ev_302.general_time= event->general_time; - ev_302.general_rows= event->general_rows; - if (get_db_mysql57(thd, &ev_302.database, &ev_302.database_length)) - { - ev_302.database= 0; - ev_302.database_length= 0; - } - ev= &ev_302; - switch (subclass_orig) - { - case MYSQL_AUDIT_GENERAL_LOG: - subclass_v3= 0; - ev_302.event_subclass= 0; - break; - case MYSQL_AUDIT_GENERAL_ERROR: - subclass_v3= 1; - ev_302.event_subclass= 1; - break; - case MYSQL_AUDIT_GENERAL_RESULT: - subclass_v3= 2; - ev_302.event_subclass= 2; - break; - case MYSQL_AUDIT_GENERAL_STATUS: - { - subclass_v3= 3; - ev_302.event_subclass= 3; - break; - } - default: - return 0; - } - } - else /* if (class == MYSQL_AUDIT_CONNECTION_CLASS) */ - { - switch (subclass_orig) - { - case MYSQL_AUDIT_CONNECTION_CONNECT: - subclass_v3= 0; - break; - case MYSQL_AUDIT_CONNECTION_DISCONNECT: - subclass_v3= 1; - break; - default: - return 0; - } - } - - *subclass= subclass_v3; - - auditing(thd, (int) class, ev); - - *subclass= subclass_orig; - return 0; -} - - -static struct st_mysql_audit mysql_descriptor = -{ - MYSQL_AUDIT_INTERFACE_VERSION, - NULL, - auditing_v4, - { (unsigned long) MYSQL_AUDIT_GENERAL_ALL, - (unsigned long) MYSQL_AUDIT_CONNECTION_ALL, - (unsigned long) MYSQL_AUDIT_PARSE_ALL, - 0, /* This event class is currently not supported. */ - 0, /* This event class is currently not supported. */ - (unsigned long) MYSQL_AUDIT_GLOBAL_VARIABLE_ALL, - (unsigned long) MYSQL_AUDIT_SERVER_STARTUP_ALL, - (unsigned long) MYSQL_AUDIT_SERVER_SHUTDOWN_ALL, - (unsigned long) MYSQL_AUDIT_COMMAND_ALL, - (unsigned long) MYSQL_AUDIT_QUERY_ALL, - (unsigned long) MYSQL_AUDIT_STORED_PROGRAM_ALL } -#ifdef WHEN_MYSQL_BUG_FIXED - /* - By this moment MySQL just sends no notifications at all - when we request only those we actually need. - So we have to request everything and filter them inside the - handling function. - */ - { (unsigned long) MYSQL_AUDIT_GENERAL_ALL, - (unsigned long) (MYSQL_AUDIT_CONNECTION_CONNECT | - MYSQL_AUDIT_CONNECTION_DISCONNECT), - 0, - 0, /* This event class is currently not supported. */ - 0, /* This event class is currently not supported. */ - 0, - 0, - 0, - 0, - 0, - 0 - } -#endif /*WHEN_MYSQL_BUG_FIXED*/ -}; - - -void *mysql_v4_descriptor= &mysql_descriptor; - From cadc958d37da6fed2f0b169db1ee950bc9fd74e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 19 Nov 2025 10:45:51 +0200 Subject: [PATCH 2/6] MDEV-38126: Convert plugin/server_audit to C++11 To be able to improve performance, let us move from C90 to C++11, which introduced std::atomic. --- plugin/server_audit/CMakeLists.txt | 2 +- .../{server_audit.c => server_audit.cc} | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) rename plugin/server_audit/{server_audit.c => server_audit.cc} (99%) diff --git a/plugin/server_audit/CMakeLists.txt b/plugin/server_audit/CMakeLists.txt index a30f431b92e5e..30249132e5343 100644 --- a/plugin/server_audit/CMakeLists.txt +++ b/plugin/server_audit/CMakeLists.txt @@ -13,6 +13,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA -SET(SOURCES server_audit.c) +SET(SOURCES server_audit.cc) MYSQL_ADD_PLUGIN(server_audit ${SOURCES} MODULE_ONLY RECOMPILE_FOR_EMBEDDED) diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.cc similarity index 99% rename from plugin/server_audit/server_audit.c rename to plugin/server_audit/server_audit.cc index 57c9ada2d51bb..b007c61102971 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.cc @@ -380,7 +380,7 @@ static struct st_mysql_show_var audit_status[]= {"server_audit_current_log", current_log_buf, SHOW_CHAR}, {"server_audit_writes_failed", (char *)&log_write_failures, SHOW_LONG}, {"server_audit_last_error", last_error_buf, SHOW_CHAR}, - {0,0,0} + {0,0,SHOW_UNDEF} }; #ifdef HAVE_PSI_INTERFACE @@ -539,10 +539,9 @@ static int coll_insert(struct user_coll *c, char *n, size_t len) if (c->n_users >= c->n_alloced) { c->n_alloced+= 128; - if (c->users == NULL) - c->users= malloc(c->n_alloced * sizeof(c->users[0])); - else - c->users= realloc(c->users, c->n_alloced * sizeof(c->users[0])); + const size_t size{c->n_alloced * sizeof *c->users}; + c->users= static_cast + (c->users ? realloc(c->users, size) : malloc(size)); if (c->users == NULL) return 1; @@ -1743,7 +1742,7 @@ static int log_statement_ex(struct connection_info *cn, { const char *orig_query= query; - if ((query= skip_set_statement(query)) == SQLCOM_NOTHING) + if (!(query= skip_set_statement(query))) return 0; if (events & EVENT_QUERY_DDL) @@ -1787,7 +1786,7 @@ static int log_statement_ex(struct connection_info *cn, if (query_len > (message_size - csize)/2) { size_t big_buffer_alloced= (query_len * 2 + csize + 4095) & ~4095L; - if(!(big_buffer= malloc(big_buffer_alloced))) + if (!(big_buffer= static_cast(malloc(big_buffer_alloced)))) return 0; memcpy(big_buffer, message, csize); @@ -2333,7 +2332,8 @@ static int init_done= 0; static int server_audit_init(void *p __attribute__((unused))) { - thd_priv_host_ptr= dlsym(RTLD_DEFAULT, "thd_priv_host"); + thd_priv_host_ptr= reinterpret_cast + (dlsym(RTLD_DEFAULT, "thd_priv_host")); if (gethostname(servhost, sizeof(servhost))) strcpy(servhost, "unknown"); @@ -2845,14 +2845,14 @@ static void update_syslog_ident(MYSQL_THD thd __attribute__((unused)), IF_WIN(static,__attribute__ ((constructor))) -void audit_plugin_so_init(void) +void audit_plugin_so_init() { memset(locinfo_ini_value, 'O', sizeof(locinfo_ini_value)-1); locinfo_ini_value[sizeof(locinfo_ini_value)-1]= 0; } #ifdef _WIN32 -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID) { if (fdwReason == DLL_PROCESS_ATTACH) audit_plugin_so_init(); From 1c8b9a03b3f2596b75b0bfeb4321f7290888d674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 19 Nov 2025 10:47:05 +0200 Subject: [PATCH 3/6] MDEV-38126: Remove __attribute__((unused)) from plugin/server_audit Starting with ISO/IEC 14882:1998 (C++98), unused function parameters may be identified simply by omitting their names. --- plugin/server_audit/server_audit.cc | 136 ++++++++++++---------------- 1 file changed, 60 insertions(+), 76 deletions(-) diff --git a/plugin/server_audit/server_audit.cc b/plugin/server_audit/server_audit.cc index b007c61102971..4bc6b22b7be7f 100644 --- a/plugin/server_audit/server_audit.cc +++ b/plugin/server_audit/server_audit.cc @@ -99,13 +99,6 @@ static void closelog() {} #else #define PLUGIN_DEBUG_VERSION "" #endif /*DBUG_OFF*/ -/* - Disable __attribute__() on non-gcc compilers. -*/ -#if !defined(__attribute__) && !defined(__GNUC__) -#define __attribute__(A) -#endif - #ifdef _WIN32 #define localtime_r(a, b) localtime_s(b, a) #endif /*WIN32*/ @@ -404,8 +397,7 @@ static mysql_mutex_t lock_atomic; } while (0) -static uchar *getkey_user(const char *entry, size_t *length, - my_bool nu __attribute__((unused)) ) +static uchar *getkey_user(const char *entry, size_t *length, my_bool) { const char *e= entry; while (*e && *e != ' ' && *e != ',') @@ -2330,7 +2322,7 @@ typedef struct loc_system_variables static int init_done= 0; -static int server_audit_init(void *p __attribute__((unused))) +static int server_audit_init(void*) { thd_priv_host_ptr= reinterpret_cast (dlsym(RTLD_DEFAULT, "thd_priv_host")); @@ -2408,7 +2400,7 @@ static int server_audit_init(void *p __attribute__((unused))) } -static int server_audit_deinit(void *p __attribute__((unused))) +static int server_audit_deinit(void *) { if (!init_done) return 0; @@ -2431,22 +2423,20 @@ static int server_audit_deinit(void *p __attribute__((unused))) } -static void rotate_log(MYSQL_THD thd __attribute__((unused)), - struct st_mysql_sys_var *var __attribute__((unused)), - void *var_ptr __attribute__((unused)), - const void *save __attribute__((unused))) +static void rotate_log(MYSQL_THD, st_mysql_sys_var *, void *, + const void *save) { - if (output_type == OUTPUT_FILE && logfile && *(my_bool*) save) + if (output_type == OUTPUT_FILE && logfile && + *static_cast(save)) (void) logger_rotate(logfile); } -static void sync_log(MYSQL_THD thd __attribute__((unused)), - struct st_mysql_sys_var *var __attribute__((unused)), - void *var_ptr __attribute__((unused)), - const void *save __attribute__((unused))) +static void sync_log(MYSQL_THD thd, st_mysql_sys_var *, void *, + const void *save) { - if (output_type == OUTPUT_FILE && logfile && *(my_bool*) save) + if (output_type == OUTPUT_FILE && logfile && + static_cast(save)) { struct connection_info *cn= get_loc_info(thd); (void) logger_sync(logfile); @@ -2508,13 +2498,13 @@ static void log_current_query(MYSQL_THD thd) } -static void update_file_path(MYSQL_THD thd, - struct st_mysql_sys_var *var __attribute__((unused)), - void *var_ptr __attribute__((unused)), const void *save) +static void update_file_path(MYSQL_THD thd, st_mysql_sys_var *, void *, + const void *save) { - char *new_name= (*(char **) save) ? *(char **) save : empty_str; - - if (strlen(new_name) + 4 > FN_REFLEN) + char *new_name= *static_cast(save); + if (!new_name) + new_name= empty_str; + else if (strlen(new_name) + 4 > FN_REFLEN) { error_header(); fprintf(stderr, @@ -2566,11 +2556,10 @@ static void update_file_path(MYSQL_THD thd, } -static void update_file_rotations(MYSQL_THD thd __attribute__((unused)), - struct st_mysql_sys_var *var __attribute__((unused)), - void *var_ptr __attribute__((unused)), const void *save) +static void update_file_rotations(MYSQL_THD, st_mysql_sys_var *, + void *, const void *save) { - rotations= *(unsigned int *) save; + rotations= *static_cast(save); error_header(); fprintf(stderr, "Log file rotations was changed to '%d'.\n", rotations); @@ -2583,11 +2572,10 @@ static void update_file_rotations(MYSQL_THD thd __attribute__((unused)), } -static void update_file_rotate_size(MYSQL_THD thd __attribute__((unused)), - struct st_mysql_sys_var *var __attribute__((unused)), - void *var_ptr __attribute__((unused)), const void *save) +static void update_file_rotate_size(MYSQL_THD, st_mysql_sys_var *, void*, + const void *save) { - file_rotate_size= *(unsigned long long *) save; + file_rotate_size= *static_cast(save); error_header(); fprintf(stderr, "Log file rotate size was changed to '%lld'.\n", file_rotate_size); @@ -2601,14 +2589,14 @@ static void update_file_rotate_size(MYSQL_THD thd __attribute__((unused)), } -static void update_file_buffer_size(MYSQL_THD thd __attribute__((unused)), - struct st_mysql_sys_var *var __attribute__((unused)), - void *var_ptr __attribute__((unused)), const void *save) +static void update_file_buffer_size(MYSQL_THD, st_mysql_sys_var *, void *, + const void *save) { - file_buffer_size= *(unsigned int *) save; + file_buffer_size= *static_cast(save); error_header(); - fprintf(stderr, "Log file buffer size was changed to '%d'.\n", file_buffer_size); + fprintf(stderr, "Log file buffer size was changed to '%u'.\n", + file_buffer_size); if (!logging || output_type != OUTPUT_FILE) return; @@ -2649,26 +2637,25 @@ static int check_users(void *save, struct st_mysql_value *value, return 0; } -static int check_incl_users(MYSQL_THD thd __attribute__((unused)), - struct st_mysql_sys_var *var __attribute__((unused)), +static int check_incl_users(MYSQL_THD, st_mysql_sys_var *, void *save, struct st_mysql_value *value) { return check_users(save, value, sizeof(incl_user_buffer), "incl"); } -static int check_excl_users(MYSQL_THD thd __attribute__((unused)), - struct st_mysql_sys_var *var __attribute__((unused)), +static int check_excl_users(MYSQL_THD, st_mysql_sys_var *, void *save, struct st_mysql_value *value) { return check_users(save, value, sizeof(excl_user_buffer), "excl"); } -static void update_incl_users(MYSQL_THD thd, - struct st_mysql_sys_var *var __attribute__((unused)), - void *var_ptr __attribute__((unused)), const void *save) +static void update_incl_users(MYSQL_THD thd, st_mysql_sys_var *, void *, + const void *save) { - char *new_users= (*(char **) save) ? *(char **) save : empty_str; + char *new_users= *static_cast(save); + if (!new_users) + new_users= empty_str; size_t new_len= strlen(new_users) + 1; mysql_prlock_wrlock(&lock_operations); mark_always_logged(thd); @@ -2687,11 +2674,12 @@ static void update_incl_users(MYSQL_THD thd, } -static void update_excl_users(MYSQL_THD thd __attribute__((unused)), - struct st_mysql_sys_var *var __attribute__((unused)), - void *var_ptr __attribute__((unused)), const void *save) +static void update_excl_users(MYSQL_THD thd, st_mysql_sys_var *, void *, + const void *save) { - char *new_users= (*(char **) save) ? *(char **) save : empty_str; + char *new_users= *static_cast(save); + if (!new_users) + new_users= empty_str; size_t new_len= strlen(new_users) + 1; mysql_prlock_wrlock(&lock_operations); mark_always_logged(thd); @@ -2710,11 +2698,10 @@ static void update_excl_users(MYSQL_THD thd __attribute__((unused)), } -static void update_output_type(MYSQL_THD thd, - struct st_mysql_sys_var *var __attribute__((unused)), - void *var_ptr __attribute__((unused)), const void *save) +static void update_output_type(MYSQL_THD thd, st_mysql_sys_var *, void *, + const void *save) { - ulong new_output_type= *((ulong *) save); + ulong new_output_type= *static_cast(save); if (output_type == new_output_type) return; @@ -2738,11 +2725,10 @@ static void update_output_type(MYSQL_THD thd, } -static void update_syslog_facility(MYSQL_THD thd __attribute__((unused)), - struct st_mysql_sys_var *var __attribute__((unused)), - void *var_ptr __attribute__((unused)), const void *save) +static void update_syslog_facility(MYSQL_THD thd, st_mysql_sys_var *, void *, + const void *save) { - ulong new_facility= *((ulong *) save); + ulong new_facility= *static_cast(save); if (syslog_facility == new_facility) return; @@ -2755,11 +2741,10 @@ static void update_syslog_facility(MYSQL_THD thd __attribute__((unused)), } -static void update_syslog_priority(MYSQL_THD thd __attribute__((unused)), - struct st_mysql_sys_var *var __attribute__((unused)), - void *var_ptr __attribute__((unused)), const void *save) +static void update_syslog_priority(MYSQL_THD thd, st_mysql_sys_var *, void *, + const void *save) { - ulong new_priority= *((ulong *) save); + ulong new_priority= *static_cast(save); if (syslog_priority == new_priority) return; @@ -2774,11 +2759,10 @@ static void update_syslog_priority(MYSQL_THD thd __attribute__((unused)), } -static void update_logging(MYSQL_THD thd, - struct st_mysql_sys_var *var __attribute__((unused)), - void *var_ptr __attribute__((unused)), const void *save) +static void update_logging(MYSQL_THD thd, st_mysql_sys_var *, void *, + const void *save) { - char new_logging= *(char *) save; + char new_logging= *static_cast(save); if (new_logging == logging) return; @@ -2804,11 +2788,10 @@ static void update_logging(MYSQL_THD thd, } -static void update_mode(MYSQL_THD thd __attribute__((unused)), - struct st_mysql_sys_var *var __attribute__((unused)), - void *var_ptr __attribute__((unused)), const void *save) +static void update_mode(MYSQL_THD thd, st_mysql_sys_var *, void *, + const void *save) { - unsigned int new_mode= *(unsigned int *) save; + unsigned new_mode= *static_cast(save); if (new_mode == mode) return; @@ -2823,11 +2806,12 @@ static void update_mode(MYSQL_THD thd __attribute__((unused)), } -static void update_syslog_ident(MYSQL_THD thd __attribute__((unused)), - struct st_mysql_sys_var *var __attribute__((unused)), - void *var_ptr __attribute__((unused)), const void *save) +static void update_syslog_ident(MYSQL_THD thd, st_mysql_sys_var *, void *, + const void *save) { - char *new_ident= (*(char **) save) ? *(char **) save : empty_str; + char *new_ident= *static_cast(save); + if (!new_ident) + new_ident= empty_str; strncpy(syslog_ident_buffer, new_ident, sizeof(syslog_ident_buffer)-1); syslog_ident_buffer[sizeof(syslog_ident_buffer)-1]= 0; syslog_ident= syslog_ident_buffer; From f66cfd932fdb23310834b349f28410cca42175c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 19 Nov 2025 10:48:22 +0200 Subject: [PATCH 4/6] MDEV-38126: Remove lock_atomic from plugin/server_audit internal_stop_logging: Declared as Atomic_counter --- plugin/server_audit/server_audit.cc | 46 ++++++++++------------------- 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/plugin/server_audit/server_audit.cc b/plugin/server_audit/server_audit.cc index 4bc6b22b7be7f..eb2d888ca2301 100644 --- a/plugin/server_audit/server_audit.cc +++ b/plugin/server_audit/server_audit.cc @@ -19,6 +19,7 @@ #define PLUGIN_STR_VERSION "1.6.0" #include +#include "my_counter.h" #include #ifndef _WIN32 @@ -89,11 +90,6 @@ static void closelog() {} #define USERNAME_CHAR_LENGTH 128 #endif -#define flogger_mutex_init(A,B,C) mysql_mutex_init(A, B, C) -#define flogger_mutex_destroy(A) mysql_mutex_destroy(A) -#define flogger_mutex_lock(A) mysql_mutex_lock(A) -#define flogger_mutex_unlock(A) mysql_mutex_unlock(A) - #ifndef DBUG_OFF #define PLUGIN_DEBUG_VERSION "-debug" #else @@ -119,7 +115,7 @@ static my_bool rotate= TRUE; static my_bool sync_file= TRUE; static unsigned int file_buffer_size; static char logging; -static volatile int internal_stop_logging= 0; +static Atomic_counter internal_stop_logging; static char incl_user_buffer[1024]; static char excl_user_buffer[1024]; static unsigned int query_log_limit= 0; @@ -385,17 +381,9 @@ static PSI_rwlock_info rwlock_key_list[]= }; #endif /*HAVE_PSI_INTERFACE*/ static mysql_prlock_t lock_operations; -static mysql_mutex_t lock_atomic; #define CLIENT_ERROR my_printf_error -#define ADD_ATOMIC(x, a) \ - do { \ - flogger_mutex_lock(&lock_atomic); \ - x+= a; \ - flogger_mutex_unlock(&lock_atomic); \ - } while (0) - static uchar *getkey_user(const char *entry, size_t *length, my_bool) { @@ -576,20 +564,20 @@ static int user_coll_fill(struct user_coll *c, char *users, if (cmp_user && take_over_cmp) { - ADD_ATOMIC(internal_stop_logging, 1); + internal_stop_logging++; CLIENT_ERROR(1, "User '%.*sB' was removed from the" " server_audit_excl_users.", MYF(ME_WARNING), (int) cmp_length, users); - ADD_ATOMIC(internal_stop_logging, -1); + internal_stop_logging--; blank_user(cmp_user); refill_cmp_coll= 1; } else if (cmp_user) { - ADD_ATOMIC(internal_stop_logging, 1); + internal_stop_logging++; CLIENT_ERROR(1, "User '%.*sB' is in the server_audit_incl_users, " "so wasn't added.", MYF(ME_WARNING), (int) cmp_length, users); - ADD_ATOMIC(internal_stop_logging, -1); + internal_stop_logging--; remove_user(users); continue; } @@ -2338,7 +2326,6 @@ static int server_audit_init(void*) PSI_server->register_rwlock("server_audit", rwlock_key_list, 1); #endif mysql_prlock_init(key_LOCK_operations, &lock_operations); - flogger_mutex_init(key_LOCK_operations, &lock_atomic, MY_MUTEX_INIT_FAST); coll_init(&incl_user_coll); coll_init(&excl_user_coll); @@ -2415,7 +2402,6 @@ static int server_audit_deinit(void *) closelog(); mysql_prlock_destroy(&lock_operations); - flogger_mutex_destroy(&lock_atomic); error_header(); fprintf(stderr, "STOPPED\n"); @@ -2516,7 +2502,7 @@ static void update_file_path(MYSQL_THD thd, st_mysql_sys_var *, void *, return; } - ADD_ATOMIC(internal_stop_logging, 1); + internal_stop_logging++; error_header(); fprintf(stderr, "Log file name was changed to '%s'.\n", new_name); @@ -2552,7 +2538,7 @@ static void update_file_path(MYSQL_THD thd, st_mysql_sys_var *, void *, file_path= path_buffer; exit_func: mysql_prlock_unlock(&lock_operations); - ADD_ATOMIC(internal_stop_logging, -1); + internal_stop_logging--; } @@ -2601,7 +2587,7 @@ static void update_file_buffer_size(MYSQL_THD, st_mysql_sys_var *, void *, if (!logging || output_type != OUTPUT_FILE) return; - ADD_ATOMIC(internal_stop_logging, 1); + internal_stop_logging++; mysql_prlock_wrlock(&lock_operations); if (logger_resize_buffer(logfile, file_buffer_size)) @@ -2614,7 +2600,7 @@ static void update_file_buffer_size(MYSQL_THD, st_mysql_sys_var *, void *, } mysql_prlock_unlock(&lock_operations); - ADD_ATOMIC(internal_stop_logging, -1); + internal_stop_logging--; } @@ -2705,7 +2691,7 @@ static void update_output_type(MYSQL_THD thd, st_mysql_sys_var *, void *, if (output_type == new_output_type) return; - ADD_ATOMIC(internal_stop_logging, 1); + internal_stop_logging++; mysql_prlock_wrlock(&lock_operations); if (logging) { @@ -2721,7 +2707,7 @@ static void update_output_type(MYSQL_THD thd, st_mysql_sys_var *, void *, if (logging) start_logging(); mysql_prlock_unlock(&lock_operations); - ADD_ATOMIC(internal_stop_logging, -1); + internal_stop_logging--; } @@ -2766,7 +2752,7 @@ static void update_logging(MYSQL_THD thd, st_mysql_sys_var *, void *, if (new_logging == logging) return; - ADD_ATOMIC(internal_stop_logging, 1); + internal_stop_logging++; mysql_prlock_wrlock(&lock_operations); if ((logging= new_logging)) { @@ -2784,7 +2770,7 @@ static void update_logging(MYSQL_THD thd, st_mysql_sys_var *, void *, } mysql_prlock_unlock(&lock_operations); - ADD_ATOMIC(internal_stop_logging, -1); + internal_stop_logging--; } @@ -2795,14 +2781,14 @@ static void update_mode(MYSQL_THD thd, st_mysql_sys_var *, void *, if (new_mode == mode) return; - ADD_ATOMIC(internal_stop_logging, 1); + internal_stop_logging++; mysql_prlock_wrlock(&lock_operations); mark_always_logged(thd); error_header(); fprintf(stderr, "Logging mode was changed from %d to %d.\n", mode, new_mode); mode= new_mode; mysql_prlock_unlock(&lock_operations); - ADD_ATOMIC(internal_stop_logging, -1); + internal_stop_logging--; } From f102d1bd73b76318932681d8f4b8c9b9a8ae3ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 19 Nov 2025 15:51:46 +0200 Subject: [PATCH 5/6] MDEV-38126: Use InnoDB srw_lock_low for plugin/server_audit Replace the contention prone mysql_prlock_t with a simpler rw-lock wrapper from InnoDB, and fix several potential race conditions by making consistent use of lock_operations. This will also omit any PERFORMANCE_SCHEMA instrumentation. --- plugin/server_audit/server_audit.cc | 400 ++++++++++++++++++---------- 1 file changed, 261 insertions(+), 139 deletions(-) diff --git a/plugin/server_audit/server_audit.cc b/plugin/server_audit/server_audit.cc index eb2d888ca2301..b1cc1c08ce259 100644 --- a/plugin/server_audit/server_audit.cc +++ b/plugin/server_audit/server_audit.cc @@ -122,8 +122,8 @@ static unsigned int query_log_limit= 0; static char servhost[HOSTNAME_LENGTH+1]; static uint servhost_len; -static char *syslog_ident; -static char syslog_ident_buffer[128]= "mysql-server_auditing"; +static char syslog_ident[128]= "mysql-server_auditing"; +static char *syslog_ident_ptr= syslog_ident; struct connection_info { @@ -259,9 +259,9 @@ static MYSQL_SYSVAR_BOOL(logging, logging, update_logging, 0); static MYSQL_SYSVAR_UINT(mode, mode, PLUGIN_VAR_OPCMDARG, "Auditing mode", NULL, update_mode, 0, 0, 1, 1); -static MYSQL_SYSVAR_STR(syslog_ident, syslog_ident, PLUGIN_VAR_RQCMDARG, +static MYSQL_SYSVAR_STR(syslog_ident, syslog_ident_ptr, PLUGIN_VAR_RQCMDARG, "The SYSLOG identifier - the beginning of each SYSLOG record", - NULL, update_syslog_ident, syslog_ident_buffer); + NULL, update_syslog_ident, syslog_ident); static MYSQL_SYSVAR_STR(syslog_info, syslog_info, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC, "The string to be added to the SYSLOG record", NULL, NULL, ""); @@ -359,7 +359,7 @@ static struct st_mysql_sys_var* vars[] = { /* Status variables for SHOW STATUS */ static int is_active= 0; -static long log_write_failures= 0; +static Atomic_counter log_write_failures; static char current_log_buf[FN_REFLEN]= ""; static char last_error_buf[512]= ""; @@ -372,15 +372,9 @@ static struct st_mysql_show_var audit_status[]= {0,0,SHOW_UNDEF} }; -#ifdef HAVE_PSI_INTERFACE -static PSI_rwlock_key key_LOCK_operations; -static PSI_rwlock_info rwlock_key_list[]= -{ - { &key_LOCK_operations, "SERVER_AUDIT_plugin::lock_operations", - PSI_FLAG_GLOBAL} -}; -#endif /*HAVE_PSI_INTERFACE*/ -static mysql_prlock_t lock_operations; +#include "../../storage/innobase/include/srw_lock.h" + +static srw_lock_low lock_operations; #define CLIENT_ERROR my_printf_error @@ -1199,18 +1193,16 @@ static void change_connection(struct connection_info *cn, event->tls_version, event->tls_version_length); } -/* +/** Write to the log - - @param take_lock If set, take a read lock (or write lock on rotate). - If not set, the caller has a already taken a write lock */ -static int write_log(const char *message, size_t len, int take_lock) +static int write_log(const char *message, size_t len) { +#if defined _WIN32 || !defined SUX_LOCK_GENERIC + DBUG_ASSERT(lock_operations.is_locked_or_waiting()); +#endif int result= 0; - if (take_lock) - mysql_prlock_rdlock(&lock_operations); if (output_type == OUTPUT_FILE) { @@ -1229,11 +1221,36 @@ static int write_log(const char *message, size_t len, int take_lock) syslog_priority_codes[syslog_priority], "%s %.*s", syslog_info, (int) len, message); } - if (take_lock) - mysql_prlock_unlock(&lock_operations); + return result; } +/** + Write to the log, acquiring the lock. +*/ + +static int write_log_and_lock(const char *message, size_t len) +{ + lock_operations.rd_lock(); + int result= write_log(message, len); + lock_operations.rd_unlock(); + return result; +} + + +/** + Write to the log + + @param lock whether the caller did not acquire lock_operations +*/ +static int write_log_maybe_lock(const char *message, size_t len, bool lock) +{ + if (unlikely(!lock)) + return write_log(message, len); + else + return write_log_and_lock(message, len); +} + static size_t log_header(char *message, size_t message_len, time_t *ts, @@ -1320,7 +1337,7 @@ static int log_proxy(const struct connection_info *cn, cn->proxy_host_length, cn->proxy_host, event->status); message[csize]= '\n'; - return write_log(message, csize + 1, 1); + return write_log_and_lock(message, csize + 1); } @@ -1347,7 +1364,7 @@ static int log_connection(const struct connection_info *cn, ",%.*s,%.*s,%d", cn->db_length, cn->db, (int) obj_len, tls_obj, event->status); message[csize]= '\n'; - return write_log(message, csize + 1, 1); + return write_log_and_lock(message, csize + 1); } @@ -1372,7 +1389,7 @@ static int log_connection_event(const struct mysql_event_connection *event, ",%.*s,%.*s,%d", (int) event->database.length,event->database.str, (int) obj_len, tls_obj, event->status); message[csize]= '\n'; - return write_log(message, csize + 1, 1); + return write_log_and_lock(message, csize + 1); } @@ -1541,15 +1558,14 @@ static size_t escape_string_hide_passwords(const char *str, unsigned int len, static int do_log_user(const char *name, int len, - const char *proxy, int proxy_len, int take_lock) + const char *proxy, int proxy_len) { int result; if (!name) return 0; - if (take_lock) - mysql_prlock_rdlock(&lock_operations); + lock_operations.rd_lock(); if (incl_user_coll.n_users) { @@ -1564,8 +1580,7 @@ static int do_log_user(const char *name, int len, else result= 1; - if (take_lock) - mysql_prlock_unlock(&lock_operations); + lock_operations.rd_unlock(); return result; } @@ -1816,7 +1831,7 @@ static int log_statement_ex(struct connection_info *cn, csize+= my_snprintf(message+csize, message_size - 1 - csize, "\',%d", error_code); message[csize]= '\n'; - result= write_log(message, csize + 1, take_lock); + result= write_log_maybe_lock(message, csize + 1, take_lock); if (cn->sync_statement && output_type == OUTPUT_FILE && logfile) { @@ -1869,7 +1884,7 @@ static int log_table(const struct connection_info *cn, (int) event->database.length, event->database.str, (int) event->table.length, event->table.str); message[csize]= '\n'; - return write_log(message, csize + 1, 1); + return write_log_and_lock(message, csize + 1); } @@ -1895,7 +1910,7 @@ static int log_rename(const struct connection_info *cn, (int) event->new_database.length, event->new_database.str, (int) event->new_table.length, event->new_table.str); message[csize]= '\n'; - return write_log(message, csize + 1, 1); + return write_log_and_lock(message, csize + 1); } @@ -2123,8 +2138,7 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) if (event_class == MYSQL_AUDIT_GENERAL_CLASS && FILTER(EVENT_QUERY) && cn && (cn->log_always || do_log_user(cn->user, cn->user_length, - cn->proxy, cn->proxy_length, - 1))) + cn->proxy, cn->proxy_length))) { const struct mysql_event_general *event = (const struct mysql_event_general *) ev; @@ -2146,7 +2160,7 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) const struct mysql_event_table *event = (const struct mysql_event_table *) ev; if (do_log_user(event->user, (int) SAFE_STRLEN(event->user), - cn->proxy, cn->proxy_length, 1)) + cn->proxy, cn->proxy_length)) { switch (event->event_subclass) { @@ -2321,11 +2335,7 @@ static int server_audit_init(void*) servhost_len= (uint)strlen(servhost); logger_init_mutexes(); -#ifdef HAVE_PSI_INTERFACE - if (PSI_server) - PSI_server->register_rwlock("server_audit", rwlock_key_list, 1); -#endif - mysql_prlock_init(key_LOCK_operations, &lock_operations); + lock_operations.init(); coll_init(&incl_user_coll); coll_init(&excl_user_coll); @@ -2395,16 +2405,8 @@ static int server_audit_deinit(void *) init_done= 0; coll_free(&incl_user_coll); coll_free(&excl_user_coll); - - if (output_type == OUTPUT_FILE && logfile) - logger_close(logfile); - else if (output_type == OUTPUT_SYSLOG) - closelog(); - - mysql_prlock_destroy(&lock_operations); - - error_header(); - fprintf(stderr, "STOPPED\n"); + stop_logging(); + lock_operations.destroy(); return 0; } @@ -2502,12 +2504,11 @@ static void update_file_path(MYSQL_THD thd, st_mysql_sys_var *, void *, return; } + lock_operations.wr_lock(); internal_stop_logging++; error_header(); fprintf(stderr, "Log file name was changed to '%s'.\n", new_name); - mysql_prlock_wrlock(&lock_operations); - if (logging) log_current_query(thd); @@ -2537,60 +2538,53 @@ static void update_file_path(MYSQL_THD thd, st_mysql_sys_var *, void *, path_buffer[sizeof(path_buffer)-1]= 0; file_path= path_buffer; exit_func: - mysql_prlock_unlock(&lock_operations); internal_stop_logging--; + lock_operations.wr_unlock(); } static void update_file_rotations(MYSQL_THD, st_mysql_sys_var *, void *, const void *save) { + lock_operations.wr_lock(); rotations= *static_cast(save); error_header(); fprintf(stderr, "Log file rotations was changed to '%d'.\n", rotations); - if (!logging || output_type != OUTPUT_FILE) - return; + if (logging && output_type == OUTPUT_FILE) + logger_set_rotations(logfile, rotations); - mysql_prlock_wrlock(&lock_operations); - logger_set_rotations(logfile, rotations); - mysql_prlock_unlock(&lock_operations); + lock_operations.wr_unlock(); } static void update_file_rotate_size(MYSQL_THD, st_mysql_sys_var *, void*, const void *save) { + lock_operations.wr_lock(); file_rotate_size= *static_cast(save); error_header(); fprintf(stderr, "Log file rotate size was changed to '%lld'.\n", file_rotate_size); - if (!logging || output_type != OUTPUT_FILE) - return; - - mysql_prlock_wrlock(&lock_operations); - logger_set_filesize_limit(logfile, file_rotate_size); - mysql_prlock_unlock(&lock_operations); + if (logging && output_type == OUTPUT_FILE) + logger_set_filesize_limit(logfile, file_rotate_size); + lock_operations.wr_unlock(); } static void update_file_buffer_size(MYSQL_THD, st_mysql_sys_var *, void *, const void *save) { + lock_operations.wr_lock(); file_buffer_size= *static_cast(save); error_header(); fprintf(stderr, "Log file buffer size was changed to '%u'.\n", file_buffer_size); - if (!logging || output_type != OUTPUT_FILE) - return; - - internal_stop_logging++; - mysql_prlock_wrlock(&lock_operations); - - if (logger_resize_buffer(logfile, file_buffer_size)) + if (logging && output_type == OUTPUT_FILE && + logger_resize_buffer(logfile, file_buffer_size)) { stop_logging(); error_header(); @@ -2599,8 +2593,7 @@ static void update_file_buffer_size(MYSQL_THD, st_mysql_sys_var *, void *, MYF(ME_WARNING)); } - mysql_prlock_unlock(&lock_operations); - internal_stop_logging--; + lock_operations.wr_unlock(); } @@ -2643,12 +2636,12 @@ static void update_incl_users(MYSQL_THD thd, st_mysql_sys_var *, void *, if (!new_users) new_users= empty_str; size_t new_len= strlen(new_users) + 1; - mysql_prlock_wrlock(&lock_operations); mark_always_logged(thd); if (new_len > sizeof(incl_user_buffer)) new_len= sizeof(incl_user_buffer); + lock_operations.wr_lock(); memcpy(incl_user_buffer, new_users, new_len - 1); incl_user_buffer[new_len - 1]= 0; @@ -2656,7 +2649,7 @@ static void update_incl_users(MYSQL_THD thd, st_mysql_sys_var *, void *, user_coll_fill(&incl_user_coll, incl_users, &excl_user_coll, 1); error_header(); fprintf(stderr, "server_audit_incl_users set to '%s'.\n", incl_users); - mysql_prlock_unlock(&lock_operations); + lock_operations.wr_unlock(); } @@ -2667,12 +2660,12 @@ static void update_excl_users(MYSQL_THD thd, st_mysql_sys_var *, void *, if (!new_users) new_users= empty_str; size_t new_len= strlen(new_users) + 1; - mysql_prlock_wrlock(&lock_operations); mark_always_logged(thd); if (new_len > sizeof(excl_user_buffer)) new_len= sizeof(excl_user_buffer); + lock_operations.wr_lock(); memcpy(excl_user_buffer, new_users, new_len - 1); excl_user_buffer[new_len - 1]= 0; @@ -2680,7 +2673,7 @@ static void update_excl_users(MYSQL_THD thd, st_mysql_sys_var *, void *, user_coll_fill(&excl_user_coll, excl_users, &incl_user_coll, 0); error_header(); fprintf(stderr, "server_audit_excl_users set to '%s'.\n", excl_users); - mysql_prlock_unlock(&lock_operations); + lock_operations.wr_unlock(); } @@ -2691,8 +2684,7 @@ static void update_output_type(MYSQL_THD thd, st_mysql_sys_var *, void *, if (output_type == new_output_type) return; - internal_stop_logging++; - mysql_prlock_wrlock(&lock_operations); + lock_operations.wr_lock(); if (logging) { log_current_query(thd); @@ -2706,8 +2698,7 @@ static void update_output_type(MYSQL_THD thd, st_mysql_sys_var *, void *, if (logging) start_logging(); - mysql_prlock_unlock(&lock_operations); - internal_stop_logging--; + lock_operations.wr_unlock(); } @@ -2715,15 +2706,18 @@ static void update_syslog_facility(MYSQL_THD thd, st_mysql_sys_var *, void *, const void *save) { ulong new_facility= *static_cast(save); - if (syslog_facility == new_facility) - return; - - mark_always_logged(thd); - error_header(); - fprintf(stderr, "SysLog facility was changed from '%s' to '%s'.\n", - syslog_facility_names[syslog_facility], - syslog_facility_names[new_facility]); - syslog_facility= new_facility; + lock_operations.wr_lock(); + ulong old_facility= syslog_facility; + if (old_facility != new_facility) + { + syslog_facility= new_facility; + mark_always_logged(thd); + error_header(); + fprintf(stderr, "SysLog facility was changed from '%s' to '%s'.\n", + syslog_facility_names[old_facility], + syslog_facility_names[new_facility]); + } + lock_operations.wr_unlock(); } @@ -2731,17 +2725,18 @@ static void update_syslog_priority(MYSQL_THD thd, st_mysql_sys_var *, void *, const void *save) { ulong new_priority= *static_cast(save); - if (syslog_priority == new_priority) - return; - - mysql_prlock_wrlock(&lock_operations); - mark_always_logged(thd); - mysql_prlock_unlock(&lock_operations); - error_header(); - fprintf(stderr, "SysLog priority was changed from '%s' to '%s'.\n", - syslog_priority_names[syslog_priority], - syslog_priority_names[new_priority]); - syslog_priority= new_priority; + lock_operations.wr_lock(); + ulong old_priority= syslog_priority; + if (old_priority != new_priority) + { + syslog_priority= new_priority; + mark_always_logged(thd); + error_header(); + fprintf(stderr, "SysLog priority was changed from '%s' to '%s'.\n", + syslog_priority_names[old_priority], + syslog_priority_names[new_priority]); + } + lock_operations.wr_unlock(); } @@ -2749,28 +2744,25 @@ static void update_logging(MYSQL_THD thd, st_mysql_sys_var *, void *, const void *save) { char new_logging= *static_cast(save); - if (new_logging == logging) - return; - - internal_stop_logging++; - mysql_prlock_wrlock(&lock_operations); - if ((logging= new_logging)) + lock_operations.wr_lock(); + if (new_logging != logging) { - start_logging(); - if (!logging) + logging= new_logging; + if (new_logging) { - CLIENT_ERROR(1, "Logging was disabled.", MYF(ME_WARNING)); + start_logging(); + if (!logging) + CLIENT_ERROR(1, "Logging was disabled.", MYF(ME_WARNING)); + else + mark_always_logged(thd); + } + else + { + log_current_query(thd); + stop_logging(); } - mark_always_logged(thd); - } - else - { - log_current_query(thd); - stop_logging(); } - - mysql_prlock_unlock(&lock_operations); - internal_stop_logging--; + lock_operations.wr_unlock(); } @@ -2778,17 +2770,17 @@ static void update_mode(MYSQL_THD thd, st_mysql_sys_var *, void *, const void *save) { unsigned new_mode= *static_cast(save); - if (new_mode == mode) - return; - - internal_stop_logging++; - mysql_prlock_wrlock(&lock_operations); - mark_always_logged(thd); - error_header(); - fprintf(stderr, "Logging mode was changed from %d to %d.\n", mode, new_mode); - mode= new_mode; - mysql_prlock_unlock(&lock_operations); - internal_stop_logging--; + lock_operations.wr_lock(); + unsigned old_mode= mode; + if (new_mode != old_mode) + { + mode= new_mode; + mark_always_logged(thd); + error_header(); + fprintf(stderr, "Logging mode was changed from %u to %u.\n", + old_mode, new_mode); + } + lock_operations.wr_unlock(); } @@ -2796,21 +2788,23 @@ static void update_syslog_ident(MYSQL_THD thd, st_mysql_sys_var *, void *, const void *save) { char *new_ident= *static_cast(save); + lock_operations.wr_lock(); if (!new_ident) - new_ident= empty_str; - strncpy(syslog_ident_buffer, new_ident, sizeof(syslog_ident_buffer)-1); - syslog_ident_buffer[sizeof(syslog_ident_buffer)-1]= 0; - syslog_ident= syslog_ident_buffer; + *syslog_ident= '\0'; + else + { + strncpy(syslog_ident, new_ident, sizeof(syslog_ident)-1); + syslog_ident[sizeof(syslog_ident)-1]= 0; + } error_header(); - fprintf(stderr, "SYSYLOG ident was changed to '%s'\n", syslog_ident); - mysql_prlock_wrlock(&lock_operations); + fprintf(stderr, "SYSLOG ident was changed to '%s'\n", syslog_ident); mark_always_logged(thd); if (logging && output_type == OUTPUT_SYSLOG) { stop_logging(); start_logging(); } - mysql_prlock_unlock(&lock_operations); + lock_operations.wr_unlock(); } @@ -2828,4 +2822,132 @@ BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID) audit_plugin_so_init(); return 1; } +#elif !defined SUX_LOCK_GENERIC +# ifdef __linux__ +# include +# include +# define SRW_FUTEX(a,op,n) \ + syscall(SYS_futex, a, FUTEX_ ## op ## _PRIVATE, n, nullptr, nullptr, 0) +# elif defined __OpenBSD__ +# include +# include +# define SRW_FUTEX(a,op,n) \ + futex((volatile uint32_t*) a, FUTEX_ ## op, n, nullptr, nullptr) +# elif defined __FreeBSD__ +# include +# include +# define FUTEX_WAKE UMTX_OP_WAKE_PRIVATE +# define FUTEX_WAIT UMTX_OP_WAIT_UINT_PRIVATE +# define SRW_FUTEX(a,op,n) _umtx_op(a, FUTEX_ ## op, n, nullptr, nullptr) +# elif defined __DragonFly__ +# include +# define FUTEX_WAKE(a,n) umtx_wakeup(a,n) +# define FUTEX_WAIT(a,n) umtx_sleep(a,n,0) +# define SRW_FUTEX(a,op,n) FUTEX_ ## op((volatile int*) a, int(n)) +# else +# error "no futex support nor #define SUX_LOCK_GENERIC" +# endif + +# ifdef __GNUC__ +# pragma GCC visibility push(hidden) /* Avoid a symbol clash with InnoDB */ +# endif + +template<> inline void srw_mutex_impl::wait(uint32_t lk) noexcept +{ SRW_FUTEX(&lock, WAIT, lk); } +template<> inline void srw_mutex_impl::wake() noexcept +{ SRW_FUTEX(&lock, WAKE, 1); } +template<> inline void srw_mutex_impl::wake_all() noexcept +{ SRW_FUTEX(&lock, WAKE, INT_MAX); } +template<> inline void ssux_lock_impl::wait(uint32_t lk) noexcept +{ SRW_FUTEX(&readers, WAIT, lk); } +template<> inline void ssux_lock_impl::wake() noexcept +{ SRW_FUTEX(&readers, WAKE, 1); } + +template<> +void srw_mutex_impl::wait_and_lock() noexcept +{ + uint32_t lk= WAITER + lock.fetch_add(WAITER, std::memory_order_relaxed); + for (;;) + { + DBUG_ASSERT(~HOLDER & lk); + if (lk & HOLDER) + { + wait(lk); +#if defined __i386__||defined __x86_64__ +reload: +#endif + lk= lock.load(std::memory_order_relaxed); + } + else + { +#if defined __i386__||defined __x86_64__ + if (lock.fetch_or(HOLDER, std::memory_order_relaxed) & HOLDER) + goto reload; +#else + if ((lk= lock.fetch_or(HOLDER, std::memory_order_relaxed)) & HOLDER) + continue; + DBUG_ASSERT(lk); +#endif + std::atomic_thread_fence(std::memory_order_acquire); + return; + } + } +} + +template<> +void ssux_lock_impl::wr_wait(uint32_t lk) noexcept +{ + DBUG_ASSERT(writer.is_locked()); + DBUG_ASSERT(lk); + DBUG_ASSERT(lk < WRITER); + + lk|= WRITER; + + do + { + DBUG_ASSERT(lk > WRITER); + wait(lk); + lk= readers.load(std::memory_order_acquire); + } + while (lk != WRITER); +} + +template +void ssux_lock_impl::rd_lock_nospin() noexcept +{ + /* Subscribe to writer.wake() or write.wake_all() calls of + concurrently executing rd_wait() or writer.wr_unlock(). */ + uint32_t wl= writer.WAITER + + writer.lock.fetch_add(writer.WAITER, std::memory_order_acquire); + + for (;;) + { + if (writer.HOLDER & wl) + writer.wait(wl); + uint32_t lk= rd_lock_try_low(); + if (!lk) + break; + if (UNIV_UNLIKELY(lk == WRITER)) /* A wr_lock() just succeeded. */ + /* Immediately wake up (also) wr_lock(). We may also unnecessarily + wake up other concurrent threads that are executing rd_wait(). + If we invoked writer.wake() here to wake up just one thread, + we could wake up a rd_wait(), which then would invoke writer.wake(), + waking up possibly another rd_wait(), and we could end up doing + lots of non-productive context switching until the wr_lock() + is finally woken up. */ + writer.wake_all(); + wl= writer.lock.load(std::memory_order_acquire); + ut_ad(wl); + } + + /* Unsubscribe writer.wake() and writer.wake_all(). */ + wl= writer.lock.fetch_sub(writer.WAITER, std::memory_order_release); + ut_ad(wl); + + /* Wake any other threads that may be blocked in writer.wait(). + All other waiters than this rd_wait() would end up acquiring writer.lock + and waking up other threads on unlock(). */ + if (wl > writer.WAITER) + writer.wake_all(); +} #endif From 5676ecfbb3716937129105d98e69355e90bfa3f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 19 Nov 2025 16:50:17 +0200 Subject: [PATCH 6/6] MDEV-38126: Fix -DWITH_UBSAN=ON logger_init_mutexes(void): Define the function as taking no arguments, to avoid function pointer type mismatch. my_b_flush_io_cache(): runtime error: addition of unsigned offset ... overflowed. Cast to a signed offset. --- mysys/file_logger.c | 2 +- mysys/mf_iocache.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mysys/file_logger.c b/mysys/file_logger.c index 2cb6502074e88..496b908721553 100644 --- a/mysys/file_logger.c +++ b/mysys/file_logger.c @@ -311,7 +311,7 @@ int logger_set_rotations(LOGGER_HANDLE *log, unsigned int new_rotations) return 0; } -void logger_init_mutexes() +void logger_init_mutexes(void) { #ifdef HAVE_PSI_INTERFACE if (unlikely(PSI_server)) diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index fabd9237e1cfd..61dfbe8096475 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -1790,7 +1790,8 @@ int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock) if ((length=(size_t) (info->write_pos - info->write_buffer))) { - my_off_t eof= info->end_of_file + info->write_pos - info->append_read_pos; + my_off_t eof= info->end_of_file + + (ptrdiff_t)(info->write_pos - info->append_read_pos); if (append_cache) { if (tmp_file_track(info, eof) ||