mysqlclient 偶尔崩溃建立 TLS 连接

mysqlclient sporadically crashes making TLS connections

我正在使用 mysqlclient 从一台服务器连接到另一台服务器,即 运行 MariaDB 10.0.27。

不使用 TLS 的连接没有任何问题。大多数使用 TLS 的连接都可以正常工作。但是,有时 Python 脚本会崩溃,例如:

*** Error in `python': double free or corruption (fasttop): 0x0000000000eccea0 *** ======= Backtrace: ========= /lib/x86_64-linux-gnu/libc.so.6(+0x71ff5)[0x7f23b22f7ff5] /lib/x86_64-linux-gnu/libc.so.6(+0x77946)[0x7f23b22fd946] /lib/x86_64-linux-gnu/libc.so.6(+0x7812e)[0x7f23b22fe12e] /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.2(CRYPTO_free+0x1d)[0x7f23b057fddd] /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.2(OBJ_NAME_add+0x91)[0x7f23b0582951] /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.2(EVP_add_cipher+0x25)[0x7f23b0641a65] /usr/lib/x86_64-linux-gnu/libssl.so.1.0.2(SSL_library_init+0x11)[0x7f23b09b86b1] /usr/lib/libmysqlclient.so.18(+0x58fe4)[0x7f23ad81cfe4] /usr/lib/libmysqlclient.so.18(+0x591a4)[0x7f23ad81d1a4] /usr/lib/libmysqlclient.so.18(+0x2ab9b)[0x7f23ad7eeb9b] /usr/lib/libmysqlclient.so.18(+0x2afed)[0x7f23ad7eefed] /usr/lib/libmysqlclient.so.18(+0x28066)[0x7f23ad7ec066] /usr/lib/libmysqlclient.so.18(+0x2b2e3)[0x7f23ad7ef2e3] /usr/lib/libmysqlclient.so.18(mysql_real_connect+0xba2)[0x7f23ad7f1542] /usr/local/lib/python2.7/site-packages/_mysql.so(+0x5c82)[0x7f23add39c82] /usr/local/lib/libpython2.7.so.1.1(+0xb8e2c)[0x7f23b3004e2c] /usr/local/lib/libpython2.7.so.1.1(PyObject_Call+0x43)[0x7f23b2fa05c3] /usr/local/lib/libpython2.7.so.1.1(PyEval_EvalFrameEx+0x375e)[0x7f23b305309e] /usr/local/lib/libpython2.7.so.1.1(PyEval_EvalCodeEx+0x81c)[0x7f23b30592cc] /usr/local/lib/libpython2.7.so.1.1(+0x855ed)[0x7f23b2fd15ed] /usr/local/lib/libpython2.7.so.1.1(PyObject_Call+0x43)[0x7f23b2fa05c3] /usr/local/lib/libpython2.7.so.1.1(+0x6588c)[0x7f23b2fb188c] /usr/local/lib/libpython2.7.so.1.1(PyObject_Call+0x43)[0x7f23b2fa05c3] /usr/local/lib/libpython2.7.so.1.1(+0xbff2d)[0x7f23b300bf2d] /usr/local/lib/libpython2.7.so.1.1(+0xbe92f)[0x7f23b300a92f] /usr/local/lib/libpython2.7.so.1.1(PyObject_Call+0x43)[0x7f23b2fa05c3] /usr/local/lib/libpython2.7.so.1.1(PyEval_EvalFrameEx+0x375e)[0x7f23b305309e] /usr/local/lib/libpython2.7.so.1.1(PyEval_EvalCodeEx+0x81c)[0x7f23b30592cc] /usr/local/lib/libpython2.7.so.1.1(PyEval_EvalFrameEx+0x5cf0)[0x7f23b3055630] /usr/local/lib/libpython2.7.so.1.1(PyEval_EvalCodeEx+0x81c)[0x7f23b30592cc] /usr/local/lib/libpython2.7.so.1.1(+0x855ed)[0x7f23b2fd15ed] /usr/local/lib/libpython2.7.so.1.1(PyObject_Call+0x43)[0x7f23b2fa05c3] /usr/local/lib/libpython2.7.so.1.1(PyEval_EvalFrameEx+0x375e)[0x7f23b305309e] /usr/local/lib/libpython2.7.so.1.1(PyEval_EvalCodeEx+0x81c)[0x7f23b30592cc] /usr/local/lib/libpython2.7.so.1.1(+0x855ed)[0x7f23b2fd15ed] /usr/local/lib/libpython2.7.so.1.1(PyObject_Call+0x43)[0x7f23b2fa05c3] /usr/local/lib/libpython2.7.so.1.1(PyEval_EvalFrameEx+0x375e)[0x7f23b305309e]/usr/local/lib/libpython2.7.so.1.1(PyEval_EvalFrameEx+0x5e01)[0x7f23b3055741]/usr/local/lib/libpython2.7.so.1.1(PyEval_EvalFrameEx+0x5e01)[0x7f23b3055741]/usr/local/lib/libpython2.7.so.1.1(PyEval_EvalCodeEx+0x81c)[0x7f23b30592cc]/usr/local/lib/libpython2.7.so.1.1(+0x8551c)[0x7f23b2fd151c]/usr/local/lib/libpython2.7.so.1.1(PyObject_Call+0x43)[0x7f23b2fa05c3]/usr/local/lib/libpython2.7.so.1.1(+0x6588c)[0x7f23b2fb188c]/usr/local/lib/libpython2.7.so.1.1(PyObject_Call+0x43)[0x7f23b2fa05c3]/usr/local/lib/libpython2.7.so.1.1(PyEval_CallObjectWithKeywords+0x47)[0x7f23b304f347]/usr/local/lib/libpython2.7.so.1.1(+0x14aa22)[0x7f23b3096a22]/lib/x86_64-linux-gnu/libpthread.so.0(+0x7454)[0x7f23b2d36454]/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7f23b236eecd]

(然后是内存映射,还有单词"aborted")。

我无法找到任何方法来可靠地重现此问题,也无法确定问题发生时原始服务器或 MariaDB 服务器上发生的任何可以解释它的事情。

服务器的 TLS 设置为:

MariaDB [(none)]> show variables like "%ssl%";
+---------------+-------------------------------------------------------+                                                                                                                                                          
| Variable_name | Value                                                 |                                                                                                                                                          
+---------------+-------------------------------------------------------+                                                                                                                                                          
| have_openssl  | YES                                                   |                                                                                                                                                          
| have_ssl      | YES                                                   |                                                                                                                                                          
| ssl_ca        | /etc/ssl/private/ca-cert.pem                          |                                                                                                                                                          
| ssl_capath    |                                                       |                                                                                                                                                          
| ssl_cert      | /etc/ssl/private/client-cert.pem                      |                                                                                                                                                          
| ssl_cipher    | CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA |                                                                                                                                                          
| ssl_crl       |                                                       |                                                                                                                                                          
| ssl_crlpath   |                                                       |                                                                                                                                                          
| ssl_key       | /etc/ssl/private/client-key.pem                       |                                                                                                                                                          
+---------------+-------------------------------------------------------+     

Python 代码正在使用 ssl={"key": "/etc/ssl/private/client-key.pem", "cert": "/etc/ssl/private/client-cert.pem"} 传递 SSL 变量。这些似乎不太可能是问题所在,因为大多数连接都可以正常工作。 MariaDB 用户已设置 REQUIRE SSL,因此所有连接都需要使用 TLS。

这里出了什么问题?或者如果无法确定,我该如何进一步调查?

这似乎是 libmysqlclient(或 libssl)的上游问题。在具有 SSL 连接的线程程序中使用 mysqlclient 时似乎会出现此问题。即使连接本地化到特定线程,这也会随机发生。

我不是 100% 确定哪个版本受到影响,但我可以确认这些版本的问题:

ii libssl1.0.2:amd64 1.0.2i-1 amd64 ii libc6:amd64 2.22-6 amd64 ii libmysqlclient18 10.0.27+maria-1~sid amd64

并在这些版本中修复:

ii libssl1.0.2:amd64 1.0.2j-1 amd64 ii libc6:amd64 2.24-5 amd64 ii libmariadbclient18:amd64 10.0.28-1 amd64

另见相关 github issue