Uploaded image for project: 'MariaDB Connector/ODBC'
  1. MariaDB Connector/ODBC
  2. ODBC-512

Crash in SQLExecute after a failed parameter array execute: cached prepared statement keeps the array size

    XMLWordPrintable

Details

    • Bug
    • Status: Closed (View Workflow)
    • Major
    • Resolution: Fixed
    • 3.2.6, 3.2.10
    • 3.2.11
    • General
    • None
    • Linux x86_64 (openSUSE Tumbleweed), unixODBC 2.3.14, MariaDB Server 11.8.9; 3.2.6 = distribution package, 3.2.10 = fedora43 tarball from dlm.mariadb.com (bundled libmariadb 3.4.11)

    Description

      If a parameter array execute (SQL_ATTR_PARAMSET_SIZE > 1) fails - e.g. with a duplicate key in one of the rows - the next execute of the same SQL text on the same connection crashes, even on a new statement handle with SQL_ATTR_PARAMSET_SIZE = 1.

      The single row execute builds a bulk request (ma_stmt_execute_generate_bulk_request) - the server side prepared statement taken from the prepared statement cache apparently still has the array size of the failed execute.

      Steps to reproduce (program attached, crash.c):

      1. CREATE TABLE odbc_ps_crash (id INT PRIMARY KEY, name VARCHAR(20)); INSERT INTO odbc_ps_crash VALUES (1, 'x')
      2. statement 1: SQLPrepare "INSERT INTO odbc_ps_crash (id, name) VALUES (?, ?)", column-wise binding (SQL_C_LONG, SQL_C_CHAR), SQL_ATTR_PARAMSET_SIZE = 3, ids 2, 1, 3 -> SQLExecute fails with 23000 Duplicate entry '1' (expected). SQLFreeHandle.
      3. statement 2 (new handle): SQLPrepare of the same text, bind one row (id 10, name 'single'), SQLExecute -> SIGSEGV

      gcc -o crash crash.c -lodbc
      ./crash <DSN> <user> <password>
       
      SQLExecute (array, duplicate key expected): rc=-1 [23000] [ma-3.2.10][11.8.9-MariaDB-ubu2404]Duplicate entry '1' for key 'PRIMARY'
      SQLPrepare (single row): rc=0
      Segmentation fault (core dumped)
      

      Backtrace (3.2.10):

      #0  __memmove_avx_unaligned_erms () from /lib64/libc.so.6
      #1  store_param (...) at libmariadb/libmariadb/mariadb_stmt.c:797
      #2  ma_stmt_execute_generate_bulk_request (...) at libmariadb/libmariadb/mariadb_stmt.c:1210
      #3  ma_stmt_execute_generate_request (...) at libmariadb/libmariadb/mariadb_stmt.c:1246
      #5  mysql_stmt_execute (...) at libmariadb/libmariadb/mariadb_stmt.c:2293
      #6  mariadb::Protocol::executePreparedQuery (...) at driver/cppmini/class/Protocol.cpp:961
      #7  mariadb::ServerSidePreparedStatement::executeInternal (...)
      #8  MADB_DoExecute (Stmt=..., ParamsPushed=true) at driver/ma_statement.cpp:1086
      #9  MADB_StmtExecute (...) at driver/ma_statement.cpp:1393
      #10 MA_SQLExecute (...) at driver/ma_api_internal.cpp:1143
      

      The fault address is the parameter data itself ("single" read as a pointer: 0x656c676e6973), i.e. the single row data is processed as if it were the bulk layout.

      Observations

      • Crashes with PCALLBACK=1 (default) and PCALLBACK=0.
      • No crash with PSCACHESIZE=0, and no crash if the second statement uses a different SQL text (e.g. an extra blank) - so the prepared statement cache is involved.
      • No crash if the array execute succeeds.
      • ODBC-506 (fixed in 3.2.10) looks related but does not cover this case.

      Workaround: PSCACHESIZE=0 in the DSN, or no parameter arrays.

      The analysis and the test program were made with AI assistance (Claude); I have verified the results.

      Attachments

        Activity

          People

            Lawrin Lawrin Novitsky
            stefan5907 Stefan Vogel
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Git Integration

                Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.