Details
-
Bug
-
Status: Closed (View Workflow)
-
Critical
-
Resolution: Fixed
-
10.3.9, 10.3.10
-
MySQL 5.7.19, CentOS 7
Description
#Environment
MariaDB Audit Plugin 1.4 (included in MariaDB Server 10.3.9)
MySQL 5.7.19
CentOS 7
#Events
Using MariaDB Audit Plugin with MySQL, mysqld crashes when selecting a database by COM_INIT_DB which the user has no privileges for or does not exist.
However, if you have already run COM_INIT_DB successfully against a (valid) database at least once in the connection, mysqld do not crash even if COM_INIT_DB fails after that.
There are two ways to crash, one is "USE command" and the other is "Specifying when connecting".
(However, when I tried MySQL 5.7.23 instead of MySQL 5.7.19, mysqld also crashed in the case of "Specifying when connecting", but in the case of "USE command" it did not crash.)
"USE command"
$ mysql -u test -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
...
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> USE invalidDB
ERROR 2013 (HY000): Lost connection to MySQL server during query
"Specifying when connecting"
$ mysql -u test -p invalidDB
Enter password:
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading authorization packet', system error: 95
#Stack trace (in the case of "USE command")
01:11:04 UTC - mysqld got signal 11 ;
|
This could be because you hit a bug. It is also possible that this binary
|
or one of the libraries it was linked against is corrupt, improperly built,
|
or misconfigured. This error can also be caused by malfunctioning hardware.
|
Attempting to collect some information that could help diagnose the problem.
|
As this is a crash and something is definitely wrong, the information
|
collection process might fail.
|
|
key_buffer_size=8388608
|
read_buffer_size=131072
|
max_used_connections=12
|
max_threads=100
|
thread_count=5
|
connection_count=5
|
It is possible that mysqld could use up to
|
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 47926 K bytes of memory
|
Hope that's ok; if not, decrease some variables in the equation.
|
|
Thread pointer: 0x7f712192a030
|
Attempting backtrace. You can use the following information to find out
|
where mysqld died. If you see no messages after this, something went
|
terribly wrong...
|
stack_bottom = 7f71c591ee30 thread_stack 0x40000
|
/usr/sbin/mysqld(my_print_stacktrace+0x3b)[0xef7bcb]
|
/usr/sbin/mysqld(handle_fatal_signal+0x461)[0x7aff11]
|
/lib64/libpthread.so.0(+0x10fc0)[0x7f74d5cc4fc0]
|
/lib64/libc.so.6(+0x142862)[0x7f74d473e862]
|
/usr/lib64/mysql/plugin/server_audit.so(auditing+0xa31)[0x7f71c74c4341]
|
/usr/lib64/mysql/plugin/server_audit.so(+0xa29b)[0x7f71c74c529b]
|
/usr/sbin/mysqld(_Z18mysql_audit_notifyP3THD30mysql_event_general_subclass_tPKciS3_m+0x2a2)[0x7b0a82]
|
/usr/sbin/mysqld(_ZN12Query_logger17general_log_printEP3THD19enum_server_commandPKcz+0xcc)[0xc1375c]
|
/usr/sbin/mysqld(_Z15mysql_change_dbP3THDRK25st_mysql_const_lex_stringb+0x397)[0xc8d647]
|
/usr/sbin/mysqld(_Z16dispatch_commandP3THDPK8COM_DATA19enum_server_command+0x8c9)[0xcc9ba9]
|
/usr/sbin/mysqld(_Z10do_commandP3THD+0x19f)[0xccb79f]
|
/usr/sbin/mysqld(handle_connection+0x288)[0xd8ad38]
|
/usr/sbin/mysqld(pfs_spawn_thread+0x1b4)[0x126de04]
|
/lib64/libpthread.so.0(+0x86e5)[0x7f74d5cbc6e5]
|
/lib64/libc.so.6(clone+0x6d)[0x7f74d46f913d]
|
|
Trying to get some variables.
|
Some pointers may be invalid and cause the dump to abort.
|
Query (0): Connection ID (thread ID): 304833
|
Status: NOT_KILLED
|
#Core dump (in the case of "USE command")
[Thread debugging using libthread_db enabled]
|
Using host libthread_db library "/lib64/libthread_db.so.1".
|
Core was generated by `/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid'.
|
|
Program terminated with signal 11, Segmentation fault.
|
|
#0 0x00007f51681563e1 in __pthread_kill (threadid=<optimized out>, signo=11) at ../sysdeps/unix/sysv/linux/pthread_kill.c:58
|
58 val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid),
|
Missing separate debuginfos, use: debuginfo-install mysql-community-server-5.7.19-1.el7.x86_64
|
|
(gdb) bt
|
#0 0x00007f51681563e1 in __pthread_kill (threadid=<optimized out>, signo=11) at ../sysdeps/unix/sysv/linux/pthread_kill.c:58
|
#1 0x00000000007afe85 in handle_fatal_signal (sig=11) at /export/home2/pb2/build/sb_1-23948522-1498141788.79/rpm/BUILD/mysql-5.7.19/mysql-5.7.19/sql/signal_handler.cc:220
|
#2 <signal handler called>
|
#3 __memcpy_avx_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-avx-unaligned.S:51
|
#4 0x00007f4e602e7341 in memcpy (__len=255, __src=<optimized out>, __dest=0x7f4d978d3eb0) at /usr/include/bits/string3.h:51
|
#5 get_str_n (src_len=255, src=<optimized out>, dest_size=256, dest_len=0x7f4d978d3fb0, dest=0x7f4d978d3eb0 "")
|
at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.3.9/plugin/server_audit/server_audit.c:936
|
#6 update_connection_info (after_action=<synthetic pointer>, ev=0x7f4e58253a60, event_class=0, cn=0x7f4d978d3e98)
|
at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.3.9/plugin/server_audit/server_audit.c:1859
|
#7 auditing (thd=thd@entry=0x7f4d942043b0, event_class=event_class@entry=0, ev=0x7f4e58253a60)
|
at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.3.9/plugin/server_audit/server_audit.c:2019
|
#8 0x00007f4e602e829b in auditing_v4 (thd=0x7f4d942043b0, class=MYSQL_AUDIT_GENERAL_CLASS, ev=0x7f4e58253b80)
|
at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.3.9/plugin/server_audit/test_audit_v4.c:115
|
#9 0x00000000007b0a82 in plugins_dispatch (arg=<synthetic pointer>, plugin=<optimized out>, thd=<optimized out>)
|
at /export/home2/pb2/build/sb_1-23948522-1498141788.79/rpm/BUILD/mysql-5.7.19/mysql-5.7.19/sql/sql_audit.cc:1370
|
#10 event_class_dispatch (event=0x7f4e58253b80, event_class=MYSQL_AUDIT_GENERAL_CLASS, thd=0x7f4d942043b0)
|
at /export/home2/pb2/build/sb_1-23948522-1498141788.79/rpm/BUILD/mysql-5.7.19/mysql-5.7.19/sql/sql_audit.cc:1410
|
#11 mysql_audit_notify (thd=thd@entry=0x7f4d942043b0, subclass=subclass@entry=MYSQL_AUDIT_GENERAL_LOG, subclass_name=subclass_name@entry=0x1421aa7 "MYSQL_AUDIT_GENERAL_LOG",
|
error_code=error_code@entry=0, msg=<optimized out>, msg_len=<optimized out>) at /export/home2/pb2/build/sb_1-23948522-1498141788.79/rpm/BUILD/mysql-5.7.19/mysql-5.7.19/sql/sql_audit.cc:460
|
#12 0x0000000000c1375c in mysql_audit_general_log (cmdlen=<optimized out>, cmd=<optimized out>, thd=0x7f4d942043b0)
|
at /export/home2/pb2/build/sb_1-23948522-1498141788.79/rpm/BUILD/mysql-5.7.19/mysql-5.7.19/sql/sql_audit.h:93
|
#13 Query_logger::general_log_print (this=0x1e6dac0 <query_logger>, thd=thd@entry=0x7f4d942043b0, command=command@entry=COM_INIT_DB, format=<optimized out>)
|
at /export/home2/pb2/build/sb_1-23948522-1498141788.79/rpm/BUILD/mysql-5.7.19/mysql-5.7.19/sql/log.cc:1501
|
#14 0x0000000000c8d647 in mysql_change_db (thd=thd@entry=0x7f4d942043b0, new_db_name=..., force_switch=force_switch@entry=false)
|
at /export/home2/pb2/build/sb_1-23948522-1498141788.79/rpm/BUILD/mysql-5.7.19/mysql-5.7.19/sql/sql_db.cc:1628
|
#15 0x0000000000cc9ba9 in dispatch_command (thd=thd@entry=0x7f4d942043b0, com_data=com_data@entry=0x7f4e58254da0, command=COM_INIT_DB)
|
at /export/home2/pb2/build/sb_1-23948522-1498141788.79/rpm/BUILD/mysql-5.7.19/mysql-5.7.19/sql/sql_parse.cc:1321
|
#16 0x0000000000ccb79f in do_command (thd=thd@entry=0x7f4d942043b0) at /export/home2/pb2/build/sb_1-23948522-1498141788.79/rpm/BUILD/mysql-5.7.19/mysql-5.7.19/sql/sql_parse.cc:999
|
#17 0x0000000000d8ad38 in handle_connection (arg=arg@entry=0x4787d9f0)
|
at /export/home2/pb2/build/sb_1-23948522-1498141788.79/rpm/BUILD/mysql-5.7.19/mysql-5.7.19/sql/conn_handler/connection_handler_per_thread.cc:300
|
#18 0x000000000126de04 in pfs_spawn_thread (arg=0x365bfc0) at /export/home2/pb2/build/sb_1-23948522-1498141788.79/rpm/BUILD/mysql-5.7.19/mysql-5.7.19/storage/perfschema/pfs.cc:2188
|
#19 0x00007f51681506e5 in start_thread (arg=0x7f4e58255700) at pthread_create.c:333
|
#20 0x00007f5166b8d13d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109
|
#Reason/Source
Looking at "auditing_v4" method (plugin/server_audit/test_audit_v4.c), it passes "ev"(type is "mysql_event_general_302" defined in test_audit_v4.c) into "auditing" method (plugin/server_audit/server_audit.c), then passes it into "update_connection_info" method (plugin/server_audit/server_audit.c).
But in the method, the "ev" is used as the type of "mysql_event_general" not the type of "mysql_event_general_302".
And in the same method, in the case of mysql 5.7, invalid parameters(event->database.str, event->database.length) for the "mysql_event_general_302" are passed into "get_str_n" method.
Then in the method, "memcpy" using invalid "src" and "src_len" causes segmentation fault and mysqld crashes.
https://github.com/MariaDB/server/blob/10.3/plugin/server_audit/test_audit_v4.c#L22-L39
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;
|
int database_length;
|
};
|
https://github.com/MariaDB/server/blob/10.3/plugin/server_audit/test_audit_v4.c#L42-L115
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;
|
.
|
.
|
.
|
ev= &ev_302;
|
.
|
.
|
.
|
auditing(thd, (int) class, ev);
|
https://github.com/MariaDB/server/blob/10.3/plugin/server_audit/server_audit.c#L1978-L2019
void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev)
|
{
|
.
|
.
|
.
|
update_connection_info(cn, event_class, ev, &after_action);
|
https://github.com/MariaDB/server/blob/10.3/plugin/server_audit/server_audit.c#L1838-L1860
static void update_connection_info(struct connection_info *cn,
|
unsigned int event_class, const void *ev, int *after_action)
|
{
|
*after_action= 0;
|
|
switch (event_class) {
|
case MYSQL_AUDIT_GENERAL_CLASS:
|
{
|
const struct mysql_event_general *event =
|
(const struct mysql_event_general *) ev;
|
.
|
.
|
.
|
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);
|
https://github.com/MariaDB/server/blob/10.3/plugin/server_audit/server_audit.c#L930-L939
static void get_str_n(char *dest, int *dest_len, size_t dest_size,
|
const char *src, size_t src_len)
|
{
|
if (src_len >= dest_size)
|
src_len= dest_size - 1;
|
|
memcpy(dest, src, src_len);
|
dest[src_len]= 0;
|
*dest_len= (int)src_len;
|
}
|