Bug #116179 mysql-connector-python
Submitted: 20 Sep 2024 11:15 Modified: 20 Sep 2024 13:46
Reporter: Felix Sterzelmaier Email Updates:
Status: Can't repeat Impact on me:
None 
Category:Connector / Python Severity:S2 (Serious)
Version:8.3.0-9.0.0 OS:Red Hat
Assigned to: CPU Architecture:Any
Tags: MySQLPrepStmt_execute, sigabrt

[20 Sep 2024 11:15] Felix Sterzelmaier
Description:
I wrote a python programm, which uses mysql-connector-python (9.0.0). I think my Python code is correct but the Programm crashes: corrupted size vs. prev_size

When debugging using the gdb backtrace command i see the following:

#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff6e45e65 in __GI_abort () at abort.c:79
#2  0x00007ffff6eb3727 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff6fbddd8 "%s\n") at ../sysdeps/posix/libc_fatal.c:181                                            
#3  0x00007ffff6ebaa2c in malloc_printerr (str=str@entry=0x7ffff6fbb78a "corrupted size vs. prev_size") at malloc.c:5449                                                                     
#4  0x00007ffff6ebb2d6 in unlink_chunk (p=p@entry=0xe1c860, av=0x7ffff71f4bc0 <main_arena>) at malloc.c:1484                                                                                 
#5  0x00007ffff6ebc95b in _int_free (av=0x7ffff71f4bc0 <main_arena>, p=0xe1c540, have_lock=<optimized out>) at malloc.c:4420                                                                 
#6  0x00007ffff36c0ada in MySQLPrepStmt_execute (self=0x7fffed3fce90, args=('nb-dt-118', <datetime.datetime at remote 0x7fffed5f8ea0>, 'HP ProCurve 1820-24G', 'J9980A', <decimal.Decimal at remote 0x7fffed45b7a0>, 'Hewlett-Packard GmbH', '35417fd283b3c210ab6bcd88beaad32f'), kwds=<optimized out>) at src/mysql_capi.c:3450
#7  0x0000000000438996 in cfunction_call_varargs (func=<built-in method stmt_execute of _mysql_connector.MySQLPrepStmt object at remote 0x7fffed3fce90>, args=<optimized out>, kwargs=<optimized out>) at Objects/call.c:743
#8  0x000000000043adb5 in PyCFunction_Call (func=<optimized out>, args=<optimized out>, kwargs=<optimized out>) at Objects/call.c:773                                                        
#9  0x000000000042abca in do_call_core (kwdict={'query_attrs': []}, callargs=('nb-dt-118', <datetime.datetime at remote 0x7fffed5f8ea0>, 'HP ProCurve 1820-24G', 'J9980A', <decimal.Decimal at remote 0x7fffed45b7a0>, 'Hewlett-Packard GmbH', '35417fd283b3c210ab6bcd88beaad32f'), func=<built-in method stmt_execute of _mysql_connector.MySQLPrepStmt object at remote 0x7fffed3fce90>, tstate=0x93dc10) at Python/ceval.c:4983                         
#10 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>) at Python/ceval.c:3559                                                                                           
#11 0x00000000004e4a20 in PyEval_EvalFrameEx (throwflag=0, f=Frame 0x7fffefe31800, for file /opt/pyenv/versions/3.8.9/lib/python3.8/site-packages/mysql/connector/connection_cext.py, line 659, in cmd_stmt_execute (self=<CMySQLConnection(_cmysql=<_mysql_connector.MySQL at remote 0xd6c010>, _columns=[], _plugin_dir='/opt/pyenv/versions/3.8.9/lib/python3.8/site-packages/mysql/vendor/plugin', converter=None, _MySQLConnectionAbstract__charset_id=45, _tracer=None, _span=None, otel_context_propagation=True, _client_flags=1286669, _sql_mode=None, _time_zone=None, _autocommit=True, _server_version=(5, 5, 68), _handshake={'protocol': 10, 'server_version_original': '5.5.68-MariaDB', 'server_threadid': 8937976, 'charset': None, 'server_status': None, 'auth_plugin': None, 'auth_data': None, 'capabilities': -1609566209}, _conn_attrs={'_connector_name': 'mysql-connector-python', '_connector_license': 'GPL-2.0', '_connector_version': '9.0.0', '_source_host': 'MUCDJA001'}, _user='nb_snow_prod', _password='iNzYbw5ex8LJDcei', _password1='', _password2='', _password3='', _database='netbox_...(truncated)) at Python/ceval.c:741                                                                        
#12 _PyEval_EvalCodeWithName (_co=<optimized out>, globals=<optimized out>, locals=locals@entry=0x0, args=<optimized out>, argcount=9, kwnames=0x0, kwargs=0x7fffedb28500, kwcount=0, kwstep=1, defs=0x0, defcount=0, kwdefs=0x0, closure=0x0, name='cmd_stmt_execute', qualname='CMySQLConnection.cmd_stmt_execute') at Python/ceval.c:4298                                   
#13 0x0000000000439321 in _PyFunction_Vectorcall (func=func@entry=<function at remote 0x7ffff64630d0>, stack=<optimized out>, nargsf=<optimized out>, nargsf@entry=9, kwnames=<optimized out>) at Objects/call.c:436
#14 0x000000000043aa9c in PyVectorcall_Call (callable=<function at remote 0x7ffff64630d0>, tuple=<optimized out>, kwargs=<optimized out>) at Objects/call.c:200                              
#15 0x0000000000422ea0 in do_call_core (kwdict={},

9.0.0: error (this is the newest Version 20th september 2024)
8.4.0: error
8.3.0: error
8.2.0: My code works fine in this Version

How to repeat:
unfortunately i have no code axample how to reproduce

Suggested fix:
Fix the Code (probably in MySQLPrepStmt_execute src/mysql_capi.c:3450)
[20 Sep 2024 12:38] MySQL Verification Team
Hello Felix Sterzelmaier,

Thank you for the report and feedback.
Please provide a test case(python script) which manifest the reported issue, otherwise it would be difficult for us to verify/confirm at our end.  Thank you.

regards,
Umesh
[20 Sep 2024 13:46] Felix Sterzelmaier
Unfortunately that is not so easy to do. My Script connects to a postgresql-database, does thousands of complicated selects and insers the data into a mysql database. The examplecode below repeats the prepared-statement insert that caused the error. Unfortunately if the script executes only this command no error is thrown. So the reproduction of this bug probably is more complex.

import mysql.connector
import psycopg # represents psycopg3
from psycopg.rows import dict_row

#connect to mysql database
conn_target = mysql.connector.connect(
    host=config.target_ip,
    port=config.target_port,
    user=config.target_user,
    password=config.target_password,
    database=config.target_database
)
conn_target.autocommit = True
#cursor
cursor_target = conn_target.cursor(prepared=True)
a = "INSERT INTO devicetype (id, last_updated, model, part_number, u_height, manufacturer, servicenow_sysid) VALUES (%(id)s, %(last_updated)s, %(model)s, %(part_number)s, %(u_height)s, %(ma$
b = {'id': 'nb-dt-118', 'last_updated': datetime.datetime(2024, 9, 20, 2, 45, 25, 543143, tzinfo=ZoneInfo(key='Europe/Berlin')), 'model': 'HP ProCurve 1820-24G', 'part_number': 'J9980A', 'u_height': 1.0, 'servicenow_sysid': '35417fd283b3c210ab6bcd88beaad32f', 'manufacturer': 'Hewlett-Packard GmbH'}

# error in following line
cursor_target.execute(a,b)