Bug #91586 mysql-connector-python allows password to be wiped before connecting
Submitted: 10 Jul 2018 4:48 Modified: 26 Aug 2018 9:53
Reporter: Sam Harding Email Updates:
Status: No Feedback Impact on me:
Category:Connector / Python Severity:S3 (Non-critical)
Version: OS:Any
Assigned to: Assigned Account CPU Architecture:Any

[10 Jul 2018 4:48] Sam Harding
There is an issue with mysql-connector-python's mysql_capi.c code in the function MySQL_connect. The function takes a password parameter which it passes of to mysql_real_connect(). However, if the password is unicode, it first assigns a PyObject* u_password the UTF8String of the password, as returned from PyUnicode_AsUTF8String(). It then copies the u_password to a char* c_password, by calling PyString_AsString, and then decrefs the u_password.


The issue is that PyString_AsString does not create a copy, but instead points to the internal buffer of the given string, so in this case c_password is pointing to u_password. The code then decrefs u_password, before c_password is used as an argument to mysql_real_connect(). u_password is the only reference to that memory address at that time, so by calling decref on u_password, it allows the process to garbage collect and reuse the memory, before the c_password has been successfully read for the mysql connection. This means that it is possible for the connection to fail, as the password field has become another value by the time it tries to connect.

tldr; passing a correct unicode password to MySQL_connect means that it is possible for the connection to fail with incorrect password credentials.

How to repeat:
It is difficult to consistently reproduce this, as it requires garbage collection or another mechanism to reap the memory address of the password. On a high volume system with a number of connection calls using unicode passwords, it happens fairly frequently however.

A multithreaded application opening lots of connections with unicode passwords, whilst triggering garbage collection, will highlight the problem.

Suggested fix:
We have patched this by simply moving the mysql_real_connect call up before the PyDECREF(u_password) call.
[26 Jul 2018 9:53] Chiranjeevi Battula
Hello Sam Harding,

Thank you for the bug report.
This bug is not easy to reproduce, so developer has prepared a patch(test patch is to avoid wiped Unicode string before connecting) for you to find difference.
Can you please try to apply the "mysql_capi.diff" patch and send information to us. 

[26 Jul 2018 9:54] Chiranjeevi Battula
Test patch to avoid wiped Unicode string before connecting

Attachment: mysql_capi.diff (application/octet-stream, text), 840 bytes.

[27 Aug 2018 1:00] Bugs System
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".