Skip to content

Commit

Permalink
Bug#33300587: mysqld crash with unknown parameter and enable create_a…
Browse files Browse the repository at this point in the history
…dmin_listener_thread

Problem: Attempting to start mysqld with
--create_admin_listener_thread and an illegal parameter resulted in a
SEGV.

Solution: Make sure cleanup code checks to see if admin thread has
actually been created before trying to pthread_kill it.

Change-Id: Ia0d2dab33da7093118f4f3e929d9cb38494f6fe8
  • Loading branch information
Dyre Tjeldvoll authored and Dyre Tjeldvoll committed Nov 16, 2021
1 parent 844eb47 commit f5a6b82
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 17 deletions.
11 changes: 11 additions & 0 deletions include/my_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,17 @@ static inline void my_thread_yield() {
#endif
}

inline bool operator==(const my_thread_handle &a, const my_thread_handle &b) {
return (a.thread == b.thread
#ifdef WIN32
&& a.handle == b.handle
#endif /* WIN32 */
);
}
inline bool operator!=(const my_thread_handle &a, const my_thread_handle &b) {
return !(a == b);
}

int my_thread_create(my_thread_handle *thread, const my_thread_attr_t *attr,
my_start_routine func, void *arg);
int my_thread_join(my_thread_handle *thread, void **value_ptr);
Expand Down
42 changes: 25 additions & 17 deletions sql/conn_handler/socket_connection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1444,28 +1444,36 @@ void Mysqld_socket_listener::close_listener() {
referenced by the data member m_admin_interface_listen_socket.
*/
if (m_use_separate_thread_for_admin) {
if (admin_socket_thread_id != my_thread_handle{}) {
#ifdef _WIN32
/*
For Windows, first close the socket referenced by the data member
m_admin_interface_listen_socket. It results in return from select()
API call running from a separate thread.
*/
(void)mysql_socket_close(m_admin_interface_listen_socket);
my_thread_join(&admin_socket_thread_id, nullptr);
/*
For Windows, first close the socket referenced by the data member
m_admin_interface_listen_socket. It results in return from select()
API call running from a separate thread.
*/
(void)mysql_socket_close(m_admin_interface_listen_socket);
m_admin_interface_listen_socket.fd = INVALID_SOCKET;
my_thread_join(&admin_socket_thread_id, nullptr);
#else
// First, finish listening thread.
pthread_kill(admin_socket_thread_id.thread, SIGALRM);
my_thread_join(&admin_socket_thread_id, nullptr);
// First, finish listening thread.
pthread_kill(admin_socket_thread_id.thread, SIGALRM);
my_thread_join(&admin_socket_thread_id, nullptr);

#endif
mysql_mutex_destroy(&LOCK_start_admin_thread);
mysql_cond_destroy(&COND_start_admin_thread);
} // if (admin_socket_thread_id != my_thread_handle{})
/*
After a thread listening on admin interface finished, it is safe
to close listening socket.
to close listening socket. But socket is opened before thread is
spawned, so we may need to close the socket even if
admin_socket_thread_id has not been assigned.
*/
(void)mysql_socket_close(m_admin_interface_listen_socket);
#endif

mysql_mutex_destroy(&LOCK_start_admin_thread);
mysql_cond_destroy(&COND_start_admin_thread);
}
if (m_admin_interface_listen_socket.fd != INVALID_SOCKET) {
(void)mysql_socket_close(m_admin_interface_listen_socket);
m_admin_interface_listen_socket.fd = INVALID_SOCKET;
}
} // use_separate_thread_for_admin

#if defined(HAVE_SYS_UN_H)
if (m_unix_sockname != "" && m_unlink_sockname) {
Expand Down

0 comments on commit f5a6b82

Please sign in to comment.