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

UBSAN: Signed integer overflow: X - -Y cannot be represented in type 'long long int' in Item_func_minus::int_op on SELECT

Details

    • Bug
    • Status: Confirmed (View Workflow)
    • Major
    • Resolution: Unresolved
    • 10.5, 10.6, 10.11, 11.2(EOL), 11.4, 11.6(EOL), 11.7(EOL)
    • 10.5, 10.6, 10.11, 11.4
    • Data types

    Description

      SELECT 1-9223372036854775808;
      

      Leads to:

      CS 11.2.6 66b8d32b7514f46b1467d404d3f9ad688bbfeb4f (Optimized, UBASAN)

      Version: '11.2.6-MariaDB'  socket: '/test/UBASAN_MD171024-mariadb-11.2.6-linux-x86_64-opt/socket.sock'  port: 10920  MariaDB Server
      /test/11.2_opt_san/sql/item_func.cc:1358:8: runtime error: signed integer overflow: 1 - -9223372036854775808 cannot be represented in type 'long long int'
          #0 0x55966a6ce3e7 in Item_func_minus::int_op() /test/11.2_opt_san/sql/item_func.cc:1358
          #1 0x5596699a5e87 in Type_handler::Item_send_longlong(Item*, Protocol*, st_value*) const /test/11.2_opt_san/sql/sql_type.cc:7699
          #2 0x559668268cec in Protocol::send_result_set_row(List<Item>*) /test/11.2_opt_san/sql/protocol.cc:1333
          #3 0x55966864a4ba in select_send::send_data(List<Item>&) /test/11.2_opt_san/sql/sql_class.cc:3194
          #4 0x559668e16a01 in select_result_sink::send_data_with_check(List<Item>&, st_select_lex_unit*, unsigned long long) /test/11.2_opt_san/sql/sql_class.h:5956
          #5 0x559668e16a01 in select_result_sink::send_data_with_check(List<Item>&, st_select_lex_unit*, unsigned long long) /test/11.2_opt_san/sql/sql_class.h:5946
          #6 0x559668e16a01 in JOIN::exec_inner() /test/11.2_opt_san/sql/sql_select.cc:4909
          #7 0x559668e1b483 in JOIN::exec() /test/11.2_opt_san/sql/sql_select.cc:4820
          #8 0x559668e0894d in mysql_select(THD*, TABLE_LIST*, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) /test/11.2_opt_san/sql/sql_select.cc:5358
          #9 0x559668e0c550 in handle_select(THD*, LEX*, select_result*, unsigned long long) /test/11.2_opt_san/sql/sql_select.cc:642
          #10 0x559668941450 in execute_sqlcom_select /test/11.2_opt_san/sql/sql_parse.cc:6177
          #11 0x5596689b175f in mysql_execute_command(THD*, bool) /test/11.2_opt_san/sql/sql_parse.cc:3984
          #12 0x5596689c2482 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/11.2_opt_san/sql/sql_parse.cc:7938
          #13 0x5596689d40da in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/11.2_opt_san/sql/sql_parse.cc:1894
          #14 0x5596689e4486 in do_command(THD*, bool) /test/11.2_opt_san/sql/sql_parse.cc:1407
          #15 0x5596693b7efc in do_handle_one_connection(CONNECT*, bool) /test/11.2_opt_san/sql/sql_connect.cc:1439
          #16 0x5596693ba52c in handle_one_connection /test/11.2_opt_san/sql/sql_connect.cc:1341
          #17 0x152d3a29ca93 in start_thread nptl/pthread_create.c:447
          #18 0x152d3a329c3b in clone3 ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
      

      CS 11.2.6 12a91b57e27b979819924cf89614e6e51f24b37b (Debug)

      Version: '11.2.6-MariaDB-debug'  socket: '/test/UBASAN_MD171024-mariadb-11.2.6-linux-x86_64-dbg/socket.sock'  port: 11917  MariaDB Server
      /test/11.2_dbg_san/sql/item_func.cc:1358:8: runtime error: signed integer overflow: 1 - -9223372036854775808 cannot be represented in type 'long long int'
          #0 0x55da6b86ad09 in Item_func_minus::int_op() /test/11.2_dbg_san/sql/item_func.cc:1358
          #1 0x55da6a9ac3c8 in Item_func_hybrid_field_type::val_int_from_int_op() /test/11.2_dbg_san/sql/item_func.h:924
          #2 0x55da6a9ac3c8 in Type_handler_int_result::Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type*) const /test/11.2_dbg_san/sql/sql_type.cc:5565
          #3 0x55da698f1933 in Item_func_hybrid_field_type::val_int() /test/11.2_dbg_san/sql/item_func.h:980
          #4 0x55da6aa654d0 in Type_handler::Item_send_longlong(Item*, Protocol*, st_value*) const /test/11.2_dbg_san/sql/sql_type.cc:7699
          #5 0x55da6aacfc1a in Type_handler_longlong::Item_send(Item*, Protocol*, st_value*) const /test/11.2_dbg_san/sql/sql_type.h:5871
          #6 0x55da690a20c0 in Item::send(Protocol*, st_value*) /test/11.2_dbg_san/sql/item.h:1255
          #7 0x55da692a33ec in Protocol::send_result_set_row(List<Item>*) /test/11.2_dbg_san/sql/protocol.cc:1333
          #8 0x55da6964d912 in select_send::send_data(List<Item>&) /test/11.2_dbg_san/sql/sql_class.cc:3194
          #9 0x55da69df746d in select_result_sink::send_data_with_check(List<Item>&, st_select_lex_unit*, unsigned long long) /test/11.2_dbg_san/sql/sql_class.h:5956
          #10 0x55da69df746d in JOIN::exec_inner() /test/11.2_dbg_san/sql/sql_select.cc:4909
          #11 0x55da69dfdbd6 in JOIN::exec() /test/11.2_dbg_san/sql/sql_select.cc:4820
          #12 0x55da69debdc3 in mysql_select(THD*, TABLE_LIST*, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) /test/11.2_dbg_san/sql/sql_select.cc:5358
          #13 0x55da69df02d4 in handle_select(THD*, LEX*, select_result*, unsigned long long) /test/11.2_dbg_san/sql/sql_select.cc:642
          #14 0x55da69943dd9 in execute_sqlcom_select /test/11.2_dbg_san/sql/sql_parse.cc:6177
          #15 0x55da699a88fc in mysql_execute_command(THD*, bool) /test/11.2_dbg_san/sql/sql_parse.cc:3984
          #16 0x55da699d3351 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/11.2_dbg_san/sql/sql_parse.cc:7938
          #17 0x55da699e329b in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/11.2_dbg_san/sql/sql_parse.cc:1894
          #18 0x55da699f1b06 in do_command(THD*, bool) /test/11.2_dbg_san/sql/sql_parse.cc:1407
          #19 0x55da6a419791 in do_handle_one_connection(CONNECT*, bool) /test/11.2_dbg_san/sql/sql_connect.cc:1439
          #20 0x55da6a41acb3 in handle_one_connection /test/11.2_dbg_san/sql/sql_connect.cc:1341
          #21 0x146d32e9ca93 in start_thread nptl/pthread_create.c:447
          #22 0x146d32f29c3b in clone3 ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
      

      Setup:

      Compiled with a recent version of GCC (I used GCC 11.4.0) and:
          -DWITH_ASAN=ON -DWITH_ASAN_SCOPE=ON -DWITH_UBSAN=ON -DWSREP_LIB_WITH_ASAN=ON
      Set before execution:
          export UBSAN_OPTIONS=print_stacktrace=1
      

      Bug confirmed present in:
      MariaDB: 10.5.27 (dbg), 10.5.27 (opt), 10.6.20 (dbg), 10.6.20 (opt), 10.11.10 (dbg), 10.11.10 (opt), 11.2.6 (dbg), 11.2.6 (opt), 11.4.4 (dbg), 11.4.4 (opt), 11.6.2 (dbg), 11.6.2 (opt), 11.7.0 (dbg), 11.7.0 (opt)

      Attachments

        Activity

          UniqueID's/Stacks observed thus far:

          UBSAN|signed integer overflow: X - -Y cannot be represented in type 'long long int'|sql/item_func.cc|Item_func_minus::int_op|Item_func_hybrid_field_type::val_int_from_int_op|Type_handler_int_result::Item_func_hybrid_field_type_val_int|Item_func_hybrid_field_type::val_int
          UBSAN|signed integer overflow: X - -Y cannot be represented in type 'long long int'|sql/item_func.cc|Item_func_minus::int_op|Type_handler::Item_send_longlong|Protocol::send_result_set_row|select_send::send_data
          

          Roel Roel Van de Paar added a comment - UniqueID's/Stacks observed thus far: UBSAN|signed integer overflow: X - -Y cannot be represented in type 'long long int'|sql/item_func.cc|Item_func_minus::int_op|Item_func_hybrid_field_type::val_int_from_int_op|Type_handler_int_result::Item_func_hybrid_field_type_val_int|Item_func_hybrid_field_type::val_int UBSAN|signed integer overflow: X - -Y cannot be represented in type 'long long int'|sql/item_func.cc|Item_func_minus::int_op|Type_handler::Item_send_longlong|Protocol::send_result_set_row|select_send::send_data

          I wonder if the following patch would fix this:

          10:22:11 /mariadb/10.6/bld/mysql-test$git show 66b8d32b7514f46b1467d404d3f9ad688bbfeb4f:../../sql/item_func.cc
          10:24:16 /mariadb/10.6/bld/mysql-test$cd /mariadb/10.5
          10:24:18 /mariadb/10.5$PAGER=cat git diff
          diff --git a/sql/item_func.cc b/sql/item_func.cc
          index 553a044eb83..91e30b5800f 100644
          --- a/sql/item_func.cc
          +++ b/sql/item_func.cc
          @@ -1184,10 +1184,7 @@ longlong Item_func_plus::int_op()
               }
             }
           
          -  if (res_unsigned)
          -    res= (longlong) ((ulonglong) val0 + (ulonglong) val1);
          -  else
          -    res= val0 + val1;
          +  res= (longlong) ((ulonglong) val0 + (ulonglong) val1);
           
             return check_integer_overflow(res, res_unsigned);
           
          @@ -1350,10 +1347,8 @@ longlong Item_func_minus::int_op()
                   goto err;
               }
             }
          -  if (res_unsigned)
          -    res= (longlong) ((ulonglong) val0 - (ulonglong) val1);
          -  else
          -    res= val0 - val1;
          +
          +  res= (longlong) ((ulonglong) val0 - (ulonglong) val1);
           
             return check_integer_overflow(res, res_unsigned);
           
          

          This patch is against the 10.5 branch. I assume that the first hunk above should fix a problem with the following:

          SELECT -9223372036854775808 + -1;
          

          An overflow of signed integer data types is undefined behaviour. With unsigned integers, there is no problem. I didn’t check if check_integer_overflow() would need some adjustment as well.

          marko Marko Mäkelä added a comment - I wonder if the following patch would fix this: 10:22:11 /mariadb/10.6/bld/mysql-test$git show 66b8d32b7514f46b1467d404d3f9ad688bbfeb4f:../../sql/item_func.cc 10:24:16 /mariadb/10.6/bld/mysql-test$cd /mariadb/10.5 10:24:18 /mariadb/10.5$PAGER=cat git diff diff --git a/sql/item_func.cc b/sql/item_func.cc index 553a044eb83..91e30b5800f 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1184,10 +1184,7 @@ longlong Item_func_plus::int_op() } } - if (res_unsigned) - res= (longlong) ((ulonglong) val0 + (ulonglong) val1); - else - res= val0 + val1; + res= (longlong) ((ulonglong) val0 + (ulonglong) val1); return check_integer_overflow(res, res_unsigned); @@ -1350,10 +1347,8 @@ longlong Item_func_minus::int_op() goto err; } } - if (res_unsigned) - res= (longlong) ((ulonglong) val0 - (ulonglong) val1); - else - res= val0 - val1; + + res= (longlong) ((ulonglong) val0 - (ulonglong) val1); return check_integer_overflow(res, res_unsigned); This patch is against the 10.5 branch. I assume that the first hunk above should fix a problem with the following: SELECT -9223372036854775808 + -1; An overflow of signed integer data types is undefined behaviour. With unsigned integers, there is no problem. I didn’t check if check_integer_overflow() would need some adjustment as well.

          Thank you marko! The proposed patch resolves the bug as described above.

          FWIW, SELECT -9223372036854775808 + -1; Does not yield any UBSAN outcome on either build for me.

          bar Can you review the patch and check check_integer_overflow() also? Thank you!

          Roel Roel Van de Paar added a comment - Thank you marko ! The proposed patch resolves the bug as described above. FWIW, SELECT -9223372036854775808 + -1; Does not yield any UBSAN outcome on either build for me. bar Can you review the patch and check check_integer_overflow() also? Thank you!

          People

            bar Alexander Barkov
            Roel Roel Van de Paar
            Votes:
            0 Vote for this issue
            Watchers:
            2 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.