Bug #106583 Issue will latest version of mysql odbc drivers
Submitted: 26 Feb 2022 23:16 Modified: 6 Aug 2022 12:20
Reporter: asdf asdfs Email Updates:
Status: No Feedback Impact on me:
None 
Category:Connector / ODBC Severity:S2 (Serious)
Version: OS:Linux
Assigned to: MySQL Verification Team CPU Architecture:x86

[26 Feb 2022 23:16] asdf asdfs
Description:
Some sort of memory bug on the latest mysql-connector-odbc
Versions 8.0.21-28. 

Using pyodbc when importing the protobuf first the driver responds with 

pyodbc.Error: ('01000', "[01000] [unixODBC][Driver Manager]Can't open lib '/usr/lib64/unixODBC/libmyodbc8.so' : file not found (0) (SQLDriverConnect)")

However when not importing protobuf first it works fine.

if using the release protobuf version 4.0.0rc2 it will seg fault.
Valgrind output 

==198==  Block was alloc'd at
==198==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==198==    by 0x590453: PyUnicode_New (in /usr/bin/python3.8)
==198==    by 0x57B185: _PyUnicodeWriter_PrepareInternal (in /usr/bin/python3.8)
==198==    by 0x57C155: ??? (in /usr/bin/python3.8)
==198==    by 0x4F0CE3: ??? (in /usr/bin/python3.8)
==198==    by 0x5FA50E: ??? (in /usr/bin/python3.8)
==198==    by 0x50490D: ??? (in /usr/bin/python3.8)
==198==    by 0x56B5DF: _PyEval_EvalFrameDefault (in /usr/bin/python3.8)
==198==    by 0x5F6225: _PyFunction_Vectorcall (in /usr/bin/python3.8)
==198==    by 0x56B5DF: _PyEval_EvalFrameDefault (in /usr/bin/python3.8)
==198==    by 0x50AC5D: ??? (in /usr/bin/python3.8)
==198==    by 0x5703E5: _PyEval_EvalFrameDefault (in /usr/bin/python3.8)
==198== 
==198== Use of uninitialised value of size 8
==198==    at 0x64816FE: void std::__once_call_impl<std::_Bind_simple<void (*(google::protobuf::internal::DescriptorTable const*, bool))(google::protobuf::internal::DescriptorTable const*, bool)> >() (in /usr/local/lib/python3.8/dist-packages/google/protobuf/pyext/_message.cpython-38-x86_64-linux-gnu.so)
==198==    by 0x4A524CF: ??? (pthread_once.c:132)
==198==    by 0x7960F8F: ??? (in /usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so)
==198== 
==198== 
==198== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==198==  Bad permissions for mapped region at address 0x6E63BC0
==198==    at 0x6E63BC0: ???
==198==    by 0x4A5247E: __pthread_once_slow (pthread_once.c:116)
==198==    by 0x72587E5: void std::call_once<void (&)()>(std::once_flag&, void (&)()) (in /usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so)
==198==    by 0x7259782: my_charset_get_by_name(MY_CHARSET_LOADER*, char const*, unsigned int, int) (in /usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so)
==198==    by 0x725986E: get_charset_by_csname(char const*, unsigned int, int) (in /usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so)
==198==    by 0x720D0BB: myodbc_init() (in /usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so)
==198==    by 0x7210F5F: my_SQLAllocEnv(void**) (in /usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so)
==198==    by 0x7212303: SQLAllocHandle (in /usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so)
==198==    by 0x6DE6962: ??? (in /usr/lib/x86_64-linux-gnu/libodbc.so.2.0.0)
==198==    by 0x6E07923: SQLDriverConnectW (in /usr/lib/x86_64-linux-gnu/libodbc.so.2.0.0)
==198==    by 0x6DB9E25: Connect (connection.cpp:114)
==198==    by 0x6DB9E25: Connection_New(_object*, bool, bool, long, bool, _object*, Object&) (connection.cpp:286)
==198==    by 0x6DC3E2B: mod_connect(_object*, _object*, _object*) (pyodbcmodule.cpp:553)

How to repeat:

RUN apt -qyy update \
    &&  apt -qyy install python3 python3-pip wget unixodbc-dev \
    && wget https://cdn.mysql.com//Downloads/Connector-ODBC/8.0/mysql-connector-odbc_8.0.28-1ubuntu20.... \
    && wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-community-client-plugins_8.0.28-1ubunt... \
    && dpkg -i mysql-community-client-plugins_8.0.28-1ubuntu20.04_amd64.deb mysql-connector-odbc_8.0.28-1ubuntu20.04_amd64.deb \
    || apt-get -qyy install -f \
    && pip install pyodbc protobuf
```

start with
`docker run -it --rm 5845c89c55ca bash`

Then run this
```
python3 -c '
from google.protobuf.pyext import _message

import pyodbc

cnxn = pyodbc.connect(
    "DRIVER=MySQL ODBC 8.0 ANSI Driver;"
    "SERVER=192.168.0.199;"
    "UID=scott;PWD=tiger;"
    "DATABASE=test;"
    "charset=utf8mb4;"
)
print(f"Connected with driver version {cnxn.getinfo(pyodbc.SQL_DRIVER_VER)}")
'
```
Comment out the google.protobuf.pyext import and it works...  :exploding_head: 

Suggested fix:
Fix some malloc.
[6 Jul 2022 12:20] Bogdan Degtyariov
When looking at the error message I see the path to the driver is inside unixODBC directory, which is not the best location:

pyodbc.Error: ('01000', "[01000] [unixODBC][Driver Manager]Can't open lib '/usr/lib64/unixODBC/libmyodbc8.so' : file not found (0) (SQLDriverConnect)")

Also, libmyodbc8.so is not the right name for the file. It should be either ANSI version libmyodbc8a.so or Unicode version libmyodbc8w.so

In the stack trace the driver path is different:

/usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so

The name with "w" suggests using of the unicode version. Yet in your python code  the driver is specified as "DRIVER=MySQL ODBC 8.0 ANSI Driver;"

You need to make sure the name of the driver library is correct.

In every instance the driver is different. To make some definite conclusions it has to be the same driver file name and the same path where it is located.

The version of protobuf 4.0.0rc2 does not look like a stable version. I tried the version 4.21.2 and everything worked.
[7 Aug 2022 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".