| Bug #82118 | MYSQL_AUDIT_GENERAL_LOG event does not report database to audit plugins in 5.7 | ||
|---|---|---|---|
| Submitted: | 5 Jul 2016 17:26 | Modified: | 6 Jul 2016 14:24 |
| Reporter: | Sergei Glushchenko | Email Updates: | |
| Status: | Verified | Impact on me: | |
| Category: | MySQL Server: Security: Audit | Severity: | S3 (Non-critical) |
| Version: | 5.7.13 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
[5 Jul 2016 17:59]
MySQL Verification Team
I am unable to spot a problem. The called function gets `command` as its parameters. And it deals with it twice, both times properly, IMHO:
1)
#ifndef EMBEDDED_LIBRARY
/* Send a general log message to the audit API. */
mysql_audit_general_log(thd, command_name[(uint) command].str,
command_name[(uint) command].length);
#endif
2)
for (Log_event_handler **current_handler= general_log_handler_list;
*current_handler; )
{
error|= (*current_handler++)->log_general(thd, current_utime, user_host_buff,
user_host_len, thd->thread_id(),
command_name[(uint) command].str,
command_name[(uint) command].length,
query, query_length,
thd->variables.character_set_client);
}
[5 Jul 2016 18:45]
Sergei Glushchenko
Yes. Command is handled properly. It is "Init DB". What I am looking for is `query`.
Here is the mysql_audit_general_log from 5.6:
static inline
void mysql_audit_general_log(THD *thd, const char *cmd, uint cmdlen,
const char *query_str, size_t query_len)
and from 5.7:
inline static
int mysql_audit_general_log(THD *thd, const char *cmd, size_t cmdlen)
[5 Jul 2016 18:50]
Sergei Glushchenko
Eventually, notify function of the audit plugin will receive command="Init DB" and query="database_name" in 5.6, but in 5.7 command="Init DB" and query="".
[6 Jul 2016 14:24]
MySQL Verification Team
Hi! Your last response cleared out a matter. Verified as reported. Thank you very much !!!

Description: Lets take a look at how audit plugins get notified about mysql_change_db ('use db' in mysql cli). 5.6: in dispatch_command function: case COM_INIT_DB: { LEX_STRING tmp; status_var_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB]); thd->convert_string(&tmp, system_charset_info, packet, packet_length, thd->charset()); if (!mysql_change_db(thd, &tmp, FALSE)) { general_log_write(thd, command, thd->db, thd->db_length); my_ok(thd); } break; } Note that thd->db is the 'query' value for general_log_write. It then passed all the way down to mysql_audit_general_log which takes query_str and query_len parameters and using it instead of query stored in THD. 5.7: case COM_INIT_DB: { LEX_STRING tmp; thd->status_var.com_stat[SQLCOM_CHANGE_DB]++; thd->convert_string(&tmp, system_charset_info, com_data->com_init_db.db_name, com_data->com_init_db.length, thd->charset()); LEX_CSTRING tmp_cstr= {tmp.str, tmp.length}; if (!mysql_change_db(thd, tmp_cstr, FALSE)) { query_logger.general_log_write(thd, command, thd->db().str, thd->db().length); my_ok(thd); } break; } Looks OK so far, DB passed as 'query' value. But then general_log_write invokes mysql_audit_general_log which doesn't take query as an argument, so it is lost now and query will simply be NULL. How to repeat: Read the code. Also you should probably see it in enterprise audit plugin output. Suggested fix: Restore 5.6 behaviour.