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

MariaDB SEGV in in my_strtod_int on INSERT

Details

    Description

      The latest release version of MariaDB crashes when running the following fuzzer generated query:

      This bug could relates to a race condition, as the following query might not reliably trigger the crash. To reproduce the bug, we repeatedly feed the following query sequence to the MariaDB server using a loop, and the crash would occur after less than one hundred iterations.

      DROP DATABASE IF EXISTS test123;
      CREATE DATABASE IF NOT EXISTS test123;
      USE test123;
      CREATE TABLE v00 (c01 INT, c02 TEXT);
      CREATE INDEX i03 ON v00 (c01);
      INSERT INTO v00 (c01, c02) VALUES (0, 'abc');
      CREATE TABLE IF NOT EXISTS v00 MIN_ROWS 1234567890 CONNECTION := 'string' IGNORE SELECT * FROM v00 AS ta35554701 NATURAL STRAIGHT_JOIN v00 AS ta35554702 RIGHT OUTER JOIN v00 AS ta35554703 NATURAL LEFT OUTER JOIN v00 AS ta35554704 ON FALSE <=> TRUE NOT IN ( SELECT 'string' ) AND FALSE <=> FALSE IN ( SELECT 'string' ) || TRUE ORDER BY TRUE ASC, FALSE <=> FALSE IN ( SELECT 'string' ) FOR UPDATE;
      CREATE TABLE IF NOT EXISTS v00 STORAGE DISK IGNORE SELECT * FROM v00 AS ta29673400 CROSS JOIN v00 AS ta29673401 NATURAL LEFT OUTER JOIN v00 AS ta29673402 NATURAL RIGHT JOIN ( v00 AS ta29673403 LEFT JOIN v00 AS ta29673404 ON FALSE ) ORDER BY TRUE ASC, FALSE <=> FALSE IN ( SELECT 'string' ) FOR UPDATE;
      ALTER SEQUENCE IF EXISTS sequence_name_0 RESTART WITH + 1234567890 START := 1234567890;
      ALTER DATABASE COMMENT 'string' COMMENT := 'string';
      ALTER DATABASE COMMENT = 'string' COMMENT := 'string';
      CREATE INDEX IF NOT EXISTS i27225501 USING BTREE ON v00 ( c01 ) WAIT 1234567890 USING BTREE USING BTREE LOCK DEFAULT;
      SELECT * FROM v00 AS ta3979400 NATURAL JOIN v00 AS ta3979401 LEFT JOIN v00 AS ta3979402 USING ( c02 ) WHERE FALSE <=> FALSE IN ( SELECT 'string' ) GROUP BY TRUE DESC HAVING + INTERVAL TRUE <=> TRUE IN ( SELECT 'string' ) HOUR_MICROSECOND + TRUE <=> TRUE IN ( SELECT 'string' ) <=> TRUE IN ( SELECT 'string' );
      ALTER SEQUENCE IF EXISTS sequence_name_0 NOMAXVALUE;
      SELECT FALSE <=> FALSE IN ( SELECT 'string' ), FALSE <=> TRUE IN ( SELECT 'string' ) FROM v00 AS ta18770000 NATURAL LEFT JOIN v00 AS ta18770001 LEFT JOIN ( v00 AS ta18770002 ) USING ( c01, c02, c01 ) GROUP BY FALSE IS NOT TRUE;
      CREATE INDEX i29675701 USING BTREE ON v00 ( c02 ( 1234567890 ) ASC ) WAIT + 1234567890 USING HASH LOCK DEFAULT;
      SELECT * FROM v00, ( v00 AS ta24670301 LEFT OUTER JOIN v00 AS ta24670302 ON TRUE <=> FALSE IN ( SELECT - INTERVAL TRUE XOR FALSE <=> FALSE IN ( SELECT 'string' ) HOUR_SECOND + TRUE <=> TRUE IN ( SELECT 'string' ) <=> TRUE NOT IN ( SELECT 'string' ) OR TRUE IS NOT FALSE <=> TRUE IN ( SELECT 'string' ) ) ) GROUP BY TRUE ASC WITH ROLLUP;
      SELECT * FROM ( v00 AS ta24671100 NATURAL LEFT OUTER JOIN v00 AS ta24671101 ) INNER JOIN ( v00 AS ta24671102 NATURAL JOIN ( ( ( SELECT 'string' ) = ta24671104 ) NATURAL STRAIGHT_JOIN v00 AS ta24671103 ) ) GROUP BY TIME ( TRUE <=> FALSE IN ( SELECT 'string' ) ) + INTERVAL REPEAT ( FALSE <=> TRUE IN ( SELECT 'string' ), FALSE ) % TRUE * INTERVAL TRUE DAY_MICROSECOND + FALSE <=> FALSE IN ( SELECT 'string' ) <=> TRUE NOT IN ( SELECT 'string' ) DAY_SECOND <=> TRUE NOT IN ( SELECT 'string' );
      BACKUP UNLOCK;
      SELECT TRUE <=> COLUMN_ADD ( TRUE, FALSE, FALSE AS DECIMAL, FALSE, TRUE <=> FALSE IN ( SELECT 'string' ) ) & INTERVAL FALSE QUARTER + FALSE <=> TRUE IN ( SELECT 'string' ) IN ( SELECT TRUE <=> TRUE IN ( SELECT 'string' ) XOR TRUE && TRUE ) FROM v00, ( v00 AS ta27229601 LEFT OUTER JOIN v00 AS ta27229602 CROSS JOIN v00 AS ta27229603 USING ( c01 ) ON TRUE <=> FALSE IN ( SELECT 'string' ) ) GROUP BY CASE WHEN FALSE <=> TRUE IN ( SELECT 'string' ) || FALSE OR TRUE <=> FALSE IN ( SELECT 'string' ) THEN TRUE END MOD CASE WHEN FALSE THEN FALSE END IS NOT TRUE;
      SELECT *, TRUE <=> TRUE IN ( SELECT 'string' ) FROM v00 AS ta29677600 NATURAL LEFT JOIN ( v00 AS ta29677601 NATURAL RIGHT OUTER JOIN v00 AS ta29677602 ) LEFT JOIN v00 AS ta29677603 USING ( c02 ) WHERE FALSE <=> TRUE IN ( SELECT 'string' ) GROUP BY FALSE IN ( SELECT NOT TRUE OR TRUE <=> CASE FALSE WHEN FALSE THEN TRUE END + TIME ( - INTERVAL TRUE <=> FALSE IN ( SELECT 'string' ) MINUTE_SECOND + TRUE <=> FALSE IN ( SELECT FALSE <=> TRUE IN ( SELECT 'string' ) FROM v00 ) <=> FALSE IN ( SELECT 'string' ) ) ^ FALSE ^ CASE WHEN TRUE THEN TRUE END IN ( SELECT 'string' ) OR TRUE ) ORDER BY TRUE LIMIT ROWS EXAMINED 1234567890 LOCK IN SHARE MODE NOWAIT;
      SELECT * FROM v00 AS ta27230900 NATURAL LEFT OUTER JOIN ( SELECT 'string' ) AS ta27230902 LEFT JOIN v00 AS ta27230901 USING ( c01 ) GROUP BY TRUE IS UNKNOWN;
      SELECT * FROM ( SELECT NOT TRUE <=> TRUE IN ( SELECT 'string' ) ) ta29679500 GROUP BY NOT TRUE <=> TRUE IN ( SELECT ( SELECT 'string' ) * FALSE / TRUE % TRUE DIV LAST_VALUE ( FALSE <=> FALSE IN ( SELECT 'string' ) ) OVER ( PARTITION BY FALSE ROWS CURRENT ROW ) IS NOT NULL );
      ( SELECT * FROM v00 AS ta29680100 JOIN v00 AS ta29680101 CROSS JOIN ( v00 AS ta29680102 INNER JOIN v00 AS ta29680103 USING ( c01 ) ) RIGHT JOIN ( ( v00 AS ta29680104 INNER JOIN v00 AS ta29680105 USING ( c01 ), v00 AS ta29680106 ) ) LEFT OUTER JOIN v00 AS ta29680107 ON TRUE ON FALSE <=> FALSE IN ( SELECT NOT TRUE <=> FALSE NOT IN ( SELECT FALSE <=> TRUE IN ( SELECT 'string' ) FROM v00 AS ta29680111 ) ) LEFT JOIN v00 AS ta29680108 ON 'string' LEFT OUTER JOIN v00 AS ta29680109 RIGHT OUTER JOIN ( v00 AS ta29680110 ) ON FALSE ON NOT TRUE <=> FALSE IN ( SELECT 'string' ) ON FALSE <=> TRUE IN ( SELECT 'string' ) ON TRUE ) ORDER BY TRUE ASC LIMIT ROWS EXAMINED 1234567890 LOCK IN SHARE MODE SKIP LOCKED;
      SELECT *, FALSE <=> TRUE IN ( SELECT 'string' ), TRUE FROM v00 AS ta29680300 CROSS JOIN v00 AS ta29680301;
      SELECT * FROM ( v00 AS ta29680700 LEFT JOIN v00 AS ta29680701 ON FALSE <=> TRUE IN ( SELECT 'string' ) OR TRUE AND TRUE <=> FALSE NOT IN ( SELECT 'string' ) ) GROUP BY TRUE ORDER BY FALSE OR FALSE <=> FALSE IN ( SELECT 'string' ) || FALSE AND TRUE <=> FALSE IN ( SELECT 'string' ) ASC FETCH NEXT ROWS WITH TIES FOR UPDATE WAIT + 1234567890;
      SELECT SQL_NO_CACHE TRUE <=> TRUE IN ( SELECT 'string' ), TRUE <=> FALSE IN ( SELECT 'string' ), FALSE FROM v00 HAVING TRUE <=> FALSE - TRUE + INTERVAL FALSE > WEIGHT_STRING ( TRUE <=> TRUE IN ( SELECT 'string' ) AS BINARY ( 1234567890 ) ) DAY_HOUR IN ( SELECT 'string' ) WINDOW no_window_name AS ( PARTITION BY FALSE, FALSE <=> FALSE IN ( SELECT 'string' ) ASC, FALSE <=> FALSE IN ( SELECT 'string' ) DESC );
      SELECT * FROM v00 AS ta35559400 NATURAL LEFT JOIN v00 AS ta35559401 LEFT JOIN v00 AS ta35559402 USING ( c01 ) GROUP BY TRUE ASC, FALSE <=> TIMESTAMP ( - CASE WHEN FALSE THEN FALSE END - FALSE % CASE WHEN TRUE THEN FALSE ELSE FALSE END <=> FALSE IN ( SELECT 'string' ) ) IN ( SELECT - INTERVAL TRUE <=> TRUE IN ( SELECT 'string' ) HOUR_SECOND + FALSE + INTERVAL FALSE XOR TRUE <=> CASE WHEN TRUE THEN FALSE END & FALSE & FALSE IN ( SELECT 'string' ) HOUR_MINUTE <=> TRUE IN ( SELECT 'string' ) != FALSE );
      SELECT * FROM ( SELECT FALSE <=> FALSE IN ( SELECT 'string' ) AND FALSE <=> TRUE IN ( SELECT 'string' ) ) ta35559600 GROUP BY NOT TRUE <=> TRUE IN ( SELECT ( SELECT TRUE <=> FALSE IN ( SELECT 'string' ) OR TRUE <=> FALSE IN ( SELECT 'string' ) ) * TRUE / - ~ CASE WHEN FALSE THEN FALSE ELSE TRUE END % TRUE DIV CONVERT ( FALSE <=> TRUE IN ( SELECT 'string' ), UNSIGNED INT ) IS NOT NULL );
      SELECT TRUE <=> FALSE IN ( SELECT 'string' ) FROM ( v00 AS ta35560200 RIGHT JOIN v00 AS ta35560201 USING ( c02 ) ) GROUP BY TRUE ORDER BY TRUE <=> FALSE IN ( SELECT 'string' ) OR FALSE <=> TRUE IN ( SELECT 'string' ) DESC OFFSET 1234567890 ROW FOR UPDATE NOWAIT;
      SELECT TRUE <=> COLUMN_ADD ( TRUE, FALSE, FALSE, TRUE <=> TRUE NOT IN ( SELECT 'string' ), FALSE <=> TRUE IN ( SELECT 'string' ) XOR TRUE AS DECIMAL ( 1234567890, 1234567890 ) ) & INTERVAL FALSE QUARTER + FALSE <=> TRUE IN ( SELECT 'string' ) IN ( SELECT TRUE <=> TRUE IN ( SELECT 'string' ) XOR TRUE && TRUE ) FROM v00, ( v00 AS ta35560401 LEFT OUTER JOIN v00 AS ta35560402 CROSS JOIN v00 AS ta35560403 USING ( c02 ) ON TRUE <=> FALSE IN ( SELECT 'string' ) ) GROUP BY CASE WHEN TRUE THEN TRUE END MOD CASE WHEN FALSE THEN FALSE END IS NOT TRUE;
      SELECT * FROM ( v00 ) WHERE TRUE <=> FALSE IN ( SELECT 'string' ) WINDOW no_window_name AS ( ORDER BY FALSE, FALSE <=> TRUE IN ( SELECT 'string' ) DESC ROWS UNBOUNDED PRECEDING );
      SELECT TRUE <=> FALSE IN ( SELECT 'string' ) FROM ( v00 AS ta35561400 NATURAL LEFT OUTER JOIN v00 AS ta35561401 LEFT OUTER JOIN v00 AS ta35561402 ON FALSE <=> TRUE IN ( SELECT 'string' ) RIGHT JOIN ( v00 AS ta35561403 LEFT OUTER JOIN v00 AS ta35561404 ON TRUE ) ON FALSE <=> FALSE IN ( SELECT TRUE <=> TRUE IN ( SELECT 'string' ) ) ) GROUP BY 'string' ORDER BY FALSE <=> FALSE IN ( SELECT - INTERVAL TRUE <=> FALSE IN ( SELECT 'string' ) HOUR_SECOND + TRUE <=> FALSE IN ( SELECT 'string' ) XOR FALSE <=> FALSE IN ( SELECT 'string' ) IS UNKNOWN ) DESC OFFSET 1234567890 ROWS FETCH NEXT 1234567890 ROWS ONLY FOR UPDATE NOWAIT;
      ( SELECT FALSE <=> FALSE IN ( SELECT 'string' ) FROM v00 );
      CREATE TABLE v00 (c01 INT, c02 TEXT);
      CREATE INDEX i03 ON v00 (c01);
      INSERT INTO v00 (c01, c02) VALUES (0, 'abc');
      CREATE TABLE IF NOT EXISTS v00 MIN_ROWS 1234567890 CONNECTION := 'string' IGNORE SELECT * FROM v00 AS ta35554701 NATURAL STRAIGHT_JOIN v00 AS ta35554702 RIGHT OUTER JOIN v00 AS ta35554703 NATURAL LEFT OUTER JOIN v00 AS ta35554704 ON FALSE <=> TRUE NOT IN ( ( SELECT * FROM v00 ) LIMIT IDENT . IDENT_QUOTED OFFSET 1234567890 ROWS EXAMINED 1234567890 ) AND FALSE <=> FALSE IN ( SELECT 'string' ) || TRUE ORDER BY TRUE ASC, FALSE <=> FALSE IN ( SELECT 'string' ) FOR UPDATE;
      CREATE TABLE IF NOT EXISTS v00 MIN_ROWS 1234567890 CONNECTION := 'string' IGNORE SELECT * FROM v00 AS ta35554701 NATURAL STRAIGHT_JOIN v00 AS ta35554702 RIGHT OUTER JOIN v00 AS ta35554703 NATURAL LEFT OUTER JOIN v00 AS ta35554704 ON FALSE <=> TRUE NOT IN ( SELECT 'string' ) AND FALSE <=> FALSE IN ( SELECT 'string' ) || TRUE ORDER BY TRUE ASC, FALSE <=> FALSE IN ( SELECT 'string' ) FOR UPDATE;
      CREATE TABLE IF NOT EXISTS v00 STORAGE DISK IGNORE SELECT * FROM v00 AS ta29673400 CROSS JOIN v00 AS ta29673401 NATURAL LEFT OUTER JOIN v00 AS ta29673402 NATURAL RIGHT JOIN ( v00 AS ta29673403 LEFT JOIN v00 AS ta29673404 ON FALSE ) ORDER BY TRUE <=> TRUE IN ( SELECT 'string' ) ASC, FALSE <=> FALSE IN ( SELECT 'string' ) FOR UPDATE;
      ALTER SEQUENCE IF EXISTS sequence_name_0 RESTART NOMINVALUE;
      INSERT LOW_PRIORITY IGNORE v00 SET c02 = FALSE <=> TRUE IN ( SELECT 'string' ) ON DUPLICATE KEY UPDATE c02 = DEFAULT RETURNING VALUE ( c02 ) + FALSE ^ + INTERVAL FALSE - INTERVAL TRUE YEAR_MONTH / CASE TRUE WHEN FALSE <=> FALSE IN ( SELECT 'string' ) XOR TRUE <=> TRUE IN ( SELECT 'string' ) XOR FALSE THEN FALSE END <=> FALSE IN ( SELECT 'string' ) YEAR_MONTH + NOT TRUE && TRUE <=> FALSE NOT IN ( SELECT 'string' ) <=> FALSE IN ( SELECT 'string' );
      

      Crash stack:

      #0  0x0000000002fc68c8 in my_strtod_int (s00=0x4ce944000 <error: Cannot access memory at address 0x4ce944000>, se=0xffff785fac40, error=0xffff785fac48,
          buf=<optimized out>, buf_size=3680) at /home/mariadb/mariadb-server/strings/dtoa.c:1378
      #1  my_strtod (str=<optimized out>, end=0xffff785fac40, error=<optimized out>) at /home/mariadb/mariadb-server/strings/dtoa.c:469
      #2  0x00000000017b0168 in charset_info_st::strntod (this=0xffffa6016088, str=0x4ce944000 <error: Cannot access memory at address 0x4ce944000>, length=255,
          endptr=0xffff785fac40, error=0xffff785fac48) at /home/mariadb/mariadb-server/include/m_ctype.h:996
      #3  Value_source::Converter_strntod::Converter_strntod (this=0xffff785fac40, cs=0xffffa6016088,
          str=0x4ce944000 <error: Cannot access memory at address 0x4ce944000>, length=255) at /home/mariadb/mariadb-server/sql/field.h:217
      #4  Value_source::Converter_strntod_with_warn::Converter_strntod_with_warn (this=0xffff785fac40, thd=0xffff78862218, filter=..., cs=0xffffa6016088,
          str=0x4ce944000 <error: Cannot access memory at address 0x4ce944000>, length=255) at /home/mariadb/mariadb-server/sql/field.h:288
      #5  Field_blob::val_real (this=<optimized out>) at /home/mariadb/mariadb-server/sql/field.cc:8929
      #6  0x00000000018892a4 in Item_field::val_real (this=<optimized out>) at /home/mariadb/mariadb-server/sql/item.cc:3475
      #7  0x00000000019fc41c in Item_func_plus::real_op (this=0xffffa02f6f38) at /home/mariadb/mariadb-server/sql/item_func.cc:1111
      #8  0x000000000151e4d0 in Type_handler_real_result::Item_val_bool (this=<optimized out>, item=0xffff785f9a78)
          at /home/mariadb/mariadb-server/sql/sql_type.cc:5231
      #9  0x0000000001959e60 in Item_cond_and::val_bool (this=<optimized out>) at /home/mariadb/mariadb-server/sql/item_cmpfunc.cc:5671
      #10 0x00000000009a20c8 in Item_bool_func::val_int (this=0xffff785f9a78) at /home/mariadb/mariadb-server/sql/item_cmpfunc.h:245
      #11 0x0000000001561144 in Type_handler::Item_send_long (this=<optimized out>, item=0xffffa0233858, protocol=<optimized out>, buf=<optimized out>)
          at /home/mariadb/mariadb-server/sql/sql_type.cc:7697
      #12 Type_handler_long::Item_send (this=<optimized out>, item=0xffffa0233858, protocol=0xffff788627b0, buf=0xffff785f9aa0)
          at /home/mariadb/mariadb-server/sql/sql_type.h:5986
      #13 0x00000000009cb280 in Protocol::send_result_set_row (this=<optimized out>, row_items=<optimized out>)
          at /home/mariadb/mariadb-server/sql/protocol.cc:1353
      #14 0x0000000000ba768c in select_send::send_data (this=<optimized out>, items=...) at /home/mariadb/mariadb-server/sql/sql_class.cc:3294
      #15 0x0000000000c34a3c in write_record (thd=0xffff78862218, table=0xffffa766cc98, info=0xffff785fb890, sink=0xffffa0233ab0)
          at /home/mariadb/mariadb-server/sql/sql_insert.cc:2339
      #16 0x0000000000c28874 in mysql_insert (thd=<optimized out>, table_list=0xffffa02f08a8, fields=..., values_list=..., update_fields=..., update_values=...,
          duplic=<optimized out>, ignore=<optimized out>, result=<optimized out>) at /home/mariadb/mariadb-server/sql/sql_insert.cc:1152
      #17 0x0000000000d3f5dc in mysql_execute_command (thd=0xffff78862218, is_called_from_prepared_stmt=<optimized out>)
          at /home/mariadb/mariadb-server/sql/sql_parse.cc:4484
      #18 0x0000000000d1cd24 in mysql_parse (thd=0xffff78862218, rawbuf=<optimized out>, length=<optimized out>, parser_state=<optimized out>)
          at /home/mariadb/mariadb-server/sql/sql_parse.cc:7915
      #19 0x0000000000d120f0 in dispatch_command (command=<optimized out>, thd=<optimized out>, packet=<optimized out>, packet_length=<optimized out>,
          blocking=<optimized out>) at /home/mariadb/mariadb-server/sql/sql_parse.cc:1902
      #20 0x0000000000d1dbf4 in do_command (thd=0xffff78862218, blocking=true) at /home/mariadb/mariadb-server/sql/sql_parse.cc:1415
      #21 0x00000000012846f8 in do_handle_one_connection (connect=<optimized out>, put_in_cache=true) at /home/mariadb/mariadb-server/sql/sql_connect.cc:1415
      #22 0x00000000012841b4 in handle_one_connection (arg=0xffff810c5638) at /home/mariadb/mariadb-server/sql/sql_connect.cc:1327
      #23 0x0000000002200c38 in pfs_spawn_thread (arg=0xffff9fe09718) at /home/mariadb/mariadb-server/storage/perfschema/pfs.cc:2198
      #24 0x0000ffffabfef624 in start_thread (arg=0x883ac8 <asan_thread_start(void*)>) at pthread_create.c:477
      #25 0x0000ffffabd1166c in thread_start () at ../sysdeps/unix/sysv/linux/aarch64/clone.S:78
      

      Attachments

        Issue Links

          Activity

            People

              bar Alexander Barkov
              luy70 Yu Liang
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

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