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

Crash fetching from statement after closing and re-executing



    • Bug
    • Status: Closed (View Workflow)
    • Major
    • Resolution: Fixed
    • 3.1.9
    • 3.1.10
    • General
    • None
    • Fedora 32


      If SQL_ATTR_ROW_ARRAY_SIZE is set to a value greater than one and you close a cursor by calling SQLFreeStmt with SQL_CLOSE and then start a new query with SQLExecute then the first fetch will cause an attempt to write to the old Stmt->result buffer which was freed when the statement was closed.

      Here's a summary of the valgrind report when this is triggered:

      ==427925== Invalid write of size 8
      ==427925==    at 0x1AE91262: mthd_stmt_fetch_to_bind (mariadb_stmt.c:409 in /usr/lib64/libmariadb.so.3)
      ==427925==    by 0x1AE92DB3: mysql_stmt_fetch (mariadb_stmt.c:1459 in /usr/lib64/libmariadb.so.3)
      ==427925==    by 0x1AE3D7B4: MoveNext (ma_result.c:63 in /usr/lib64/libmaodbc.so)
      ==427925==    by 0x1AE3A344: MADB_StmtFetch (ma_statement.c:2036 in /usr/lib64/libmaodbc.so)
      ==427925==    by 0x1AE32B61: MADB_StmtFetchScroll (ma_statement.c:4596 in /usr/lib64/libmaodbc.so)
      ==427925==    by 0x1AE21916: SQLFetch (odbc_3_api.c:1415 in /usr/lib64/libmaodbc.so)
      ==427925==    by 0x1A9BAE51: SQLFetch (SQLFetch.c:301 in /usr/lib64/libodbc.so.2.0.0)
      ==427925==  Address 0x1b441040 is 80 bytes inside a block of size 336 free'd
      ==427925==    at 0x483B9F5: free (vg_replace_malloc.c:538 in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
      ==427925==    by 0x1AE3687E: MADB_StmtFree (ma_statement.c:205 in /usr/lib64/libmaodbc.so)
      ==427925==    by 0x1A9BC9E9: SQLFreeStmt (SQLFreeStmt.c:218 in /usr/lib64/libodbc.so.2.0.0)
      ==427925==  Block was alloc'd at
      ==427925==    at 0x483CAE9: calloc (vg_replace_malloc.c:760 in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
      ==427925==    by 0x1AE3A3AE: MADB_StmtFetch (ma_statement.c:2003 in /usr/lib64/libmaodbc.so)
      ==427925==    by 0x1AE32B61: MADB_StmtFetchScroll (ma_statement.c:4596 in /usr/lib64/libmaodbc.so)
      ==427925==    by 0x1AE21916: SQLFetch (odbc_3_api.c:1415 in /usr/lib64/libmaodbc.so)
      ==427925==    by 0x1A9BAE51: SQLFetch (SQLFetch.c:301 in /usr/lib64/libodbc.so.2.0.0)

      The trigger is that when doing a multi-row fetch MADB_StmtFetch tries to read the first row with MoveNext without calling mysql_stmt_bind_result to bind the result area first.

      On the first execution that is fine as no bind has been done so the C API doesn't try to write the results back.

      On the second execution the library still has the binds from the first time, and tries to write to them, but they point at the old result buffer that was freed when SQLFreeStmt was called to close the cursor.

      If we're not doing a multi-row fetch then we're fine as the new result buffer will be bound with mysql_stmt_bind_result before the rows are fetched for real - it is only this special pre-read fetch of the first row that doesn't bind first.

      It might be that this is a bug in the C connector as the close does call mysql_stmt_free_result but that doesn't currently reset the binds, and it is not clear if it is supposed to or not.


        Issue Links



              Lawrin Lawrin Novitsky
              TomH Tom Hughes
              0 Vote for this issue
              3 Start watching this issue



                Git Integration

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