Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-25216

crash in calling procedure second time using C mysql_stmt_execute API (server x86 32 bit only)



    • Type: Bug
    • Status: Open (View Workflow)
    • Priority: Critical
    • Resolution: Unresolved
    • Affects Version/s: 5.5.63, 5.5.68, 10.2.37
    • Fix Version/s: 10.2
    • Component/s: Prepared Statements
    • Labels:
    • Environment:
      x86_32, not x86_64


      From Anton Golovenko @ vmsoftware

      Hello Sergey, Daniel,

      When I was testing mariadb-connector-c I had found a bug on the MariaDB server-side (5.5.63 – 5.5.68 versions) dealing with server crashes. By the way I have checked it on 10.6 MariaDB version and error doesn’t reproduced.

      I know that you doesn’t support MariaDB 5.5 yet, but it may be useful for some users.

      After some investigations were founded that its bug reproduced only on 32-bit build (I was testing it on OpenVMS IA64 and Linux Ubuntu 16.04 32-bit) on 64-bit build this bug doesn’t reproduced (tested on Linux Ubuntu 18.04 64-bit).

      Below I show how to reproduce this bug.

      (attached at connector/C compatible tests)

      Note! Server crashes only when we use mysql API (Mariadb-connector-c or another).

      First, you should establish a connection with the MariaDB server and run a test described below. (ps.c :: 4974). In current test I have changed bind variable type from integer to string.

      NOTE! This issue appears 32-bit build only.

          longlong integer;
          double   real;
            Character sets conversion info for string values.
            Character sets of client and connection defined at bind time are used
            for all conversions, even if one of them is later changed (i.e.
            between subsequent calls to mysql_stmt_execute).
          struct CONVERSION_INFO
            CHARSET_INFO *character_set_client;
            CHARSET_INFO *character_set_of_placeholder;
              This points at character set of connection if conversion
              to it is required (i. e. if placeholder typecode is not BLOB).
              Otherwise it's equal to character_set_client (to simplify
              check in convert_str_value()).
            CHARSET_INFO *final_character_set_of_str_value;
          } cs_info;
          MYSQL_TIME     time;
        } value;

      When we execute our procedure first time, we fill in character_set_of_placeholder in setup_one_conversation_function and do it once for all executions. And when we execute SET p_in = 100, p_out = 200, p_inout = 300; procedure statement puts integer value into “value” union longlong integer field. And longlong integer takes 8 bytes and overrides 2 pointers (character_set_client and character_set_of_placeholder which takes by 4 bytes on 32-bit build) and when we try to refer to the character_set_of_placeholder we got an access violation error. But on 64-bit platform we override only character_set_client field, that also wrong but it doesn’t crush the server.

      Thus, the issue is critical because with it the server can be crashed by any API user that has privileges to create and run procedures on MariaDB 5.5 (32-bit build).


      Anton Golovenko

      Reproduces on 10.2 tarball

      I placed the wrapped up version of Anton's test (attached) had in unittest/libmariadb/crash.c and rebuild mariadb-connnector-c (on 64bit).

      diff --git a/unittest/libmariadb/CMakeLists.txt b/unittest/libmariadb/CMakeLists.txt
      index e3ba18b..08ed7a4 100644
      --- a/unittest/libmariadb/CMakeLists.txt
      +++ b/unittest/libmariadb/CMakeLists.txt
      @@ -26,7 +26,7 @@ INCLUDE_DIRECTORIES(${CC_SOURCE_DIR}/include
      -SET(API_TESTS "conc336" "bulk1" "performance" "basic-t" "fetch" "charset" "logs" "cursor" "errors" "view" "ps" "ps_bugs" "sp" "result" "connection" "misc" "ps_new" "thread" "features-10_2" "bulk1")
      +SET(API_TESTS "conc336" "bulk1" "performance" "basic-t" "fetch" "charset" "logs" "cursor" "errors" "view" "ps" "ps_bugs" "sp" "result" "connection" "misc" "ps_new" "thread" "features-10_2" "bulk1" "crash")
         SET(API_TESTS ${API_TESTS} "dyncol")

      This crashed the 32bit server as described.

      $ unittest/libmariadb/crash -u root -d test -S /tmp/mysql.sock
      # port: 0
      # ssl_port: 0
      # Testing against MySQL Server 10.2.37-MariaDB
      # Host: Localhost via UNIX socket
      # Client library: 10.5.5
      # Error: Lost connection to MySQL server during query (/home/dan/repos/mariadb-connector-c/unittest/libmariadb/crash.c: 132)
      not ok 1 - test_reexecute,
      # error: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (111)
      # Couldn't establish connection to server (null). Error (2002): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (111)
      # Failed 1 tests!

      $ ./mariadb-10.2.37-linux-systemd-i686/bin/mysqld --no-defaults --basedir=$PWD/mariadb-10.2.37-linux-systemd-i686 --datadir=/tmp/10.2 --skip-networking
      2021-03-20 16:03:51 4154480064 [Note] ./mariadb-10.2.37-linux-systemd-i686/bin/mysqld (mysqld 10.2.37-MariaDB) starting as process 256190 ...
      2021-03-20 16:03:51 4154480064 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
      2021-03-20 16:03:51 4154480064 [Note] InnoDB: Uses event mutexes
      2021-03-20 16:03:51 4154480064 [Note] InnoDB: Compressed tables use zlib 1.2.11
      2021-03-20 16:03:51 4154480064 [Note] InnoDB: Using Linux native AIO
      2021-03-20 16:03:51 4154480064 [Note] InnoDB: Number of pools: 1
      2021-03-20 16:03:51 4154480064 [Note] InnoDB: Using generic crc32 instructions
      2021-03-20 16:03:51 4154480064 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
      2021-03-20 16:03:51 4154480064 [Note] InnoDB: Completed initialization of buffer pool
      2021-03-20 16:03:51 3600054976 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
      2021-03-20 16:03:51 4154480064 [Note] InnoDB: Highest supported file format is Barracuda.
      2021-03-20 16:03:52 4154480064 [Note] InnoDB: 128 out of 128 rollback segments are active.
      2021-03-20 16:03:52 4154480064 [Note] InnoDB: Creating shared tablespace for temporary tables
      2021-03-20 16:03:52 4154480064 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
      2021-03-20 16:03:52 4154480064 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
      2021-03-20 16:03:52 4154480064 [Note] InnoDB: Waiting for purge to start
      2021-03-20 16:03:52 4154480064 [Note] InnoDB: 5.7.33 started; log sequence number 1615517
      2021-03-20 16:03:52 3491756736 [Note] InnoDB: Loading buffer pool(s) from /tmp/10.2/ib_buffer_pool
      2021-03-20 16:03:52 4154480064 [Note] Plugin 'FEEDBACK' is disabled.
      2021-03-20 16:03:52 3491756736 [Note] InnoDB: Buffer pool(s) load completed at 210320 16:03:52
      2021-03-20 16:03:52 4154480064 [Note] Reading of all Master_info entries succeeded
      2021-03-20 16:03:52 4154480064 [Note] Added new Master_info '' to hash table
      2021-03-20 16:03:52 4154480064 [Note] ./mariadb-10.2.37-linux-systemd-i686/bin/mysqld: ready for connections.
      Version: '10.2.37-MariaDB'  socket: '/tmp/mysql.sock'  port: 0  MariaDB Server
      210320 16:10:21 [ERROR] mysqld got signal 11 ;
      This could be because you hit a bug. It is also possible that this binary
      or one of the libraries it was linked against is corrupt, improperly built,
      or misconfigured. This error can also be caused by malfunctioning hardware.
      To report this bug, see https://mariadb.com/kb/en/reporting-bugs
      We will try our best to scrape up some info that will hopefully help
      diagnose the problem, but since we have already crashed,
      something is definitely wrong and this may fail.
      Server version: 10.2.37-MariaDB
      It is possible that mysqld could use up to
      key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 466068 K  bytes of memory
      Hope that's ok; if not, decrease some variables in the equation.
      Thread pointer: 0xcdc006b8
      Attempting backtrace. You can use the following information to find out
      where mysqld died. If you see no messages after this, something went
      terribly wrong...
      stack_bottom = 0xdbab42ec thread_stack 0x49000
      addr2line: './mariadb-10.2.37-linux-systemd-i686/bin/mysqld': No such file
      addr2line: 'linux-gate.so.1': No such file
      addr2line: './mariadb-10.2.37-linux-systemd-i686/bin/mysqld': No such file


        1. crash.c
          2 kB
        2. gdb.txt
          53 kB



            sanja Oleksandr Byelkin
            danblack Daniel Black
            1 Vote for this issue
            4 Start watching this issue