[MDEV-29447] SIGSEGV in spider_db_open_item_field and SIGSEGV in spider_db_print_item_type, on SELECT Created: 2022-09-02  Updated: 2023-09-22  Resolved: 2023-06-27

Status: Closed
Project: MariaDB Server
Component/s: Storage Engine - Spider
Affects Version/s: 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9, 10.10, 10.11, 11.0
Fix Version/s: 10.4.31, 10.5.22, 10.6.15, 10.9.8, 10.10.6, 10.11.5, 11.0.3, 11.1.2

Type: Bug Priority: Critical
Reporter: Roel Van de Paar Assignee: Yuchen Pei
Resolution: Fixed Votes: 0
Labels: spider-gbh

Issue Links:
Blocks
is blocked by MDEV-26285 Refactor spider_db_mbase_util::open_i... Closed
Duplicate
is duplicated by MDEV-31338 UBSAN: runtime error: member access w... Closed
Relates
relates to MDEV-30504 Further refactoring of spider_db_mbas... Open

 Description   

INSTALL PLUGIN spider SONAME 'ha_spider.so';
CREATE USER spider@localhost IDENTIFIED BY 'PWD1';
CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS(SOCKET '../socket.sock',DATABASE 'test',USER 'spider',PASSWORD 'PWD1');
CREATE TABLE t(c INT);
CREATE TABLE b(d INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"';
SELECT TRIM(LEADING 'c' FROM d) FROM b;

Leads to:

10.11.0 bc563f1a4b0b38de3b41fd0f0d3d8b7f1aacbd8b (Optimized)

Core was generated by `/test/MD190822-mariadb-10.11.0-linux-x86_64-opt/bin/mysqld --no-defaults --core'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000152265b4ec61 in spider_db_open_item_field (
    item_field=<optimized out>, spider=<optimized out>, str=0x152224062650, 
    alias=<optimized out>, alias_length=<optimized out>, dbton_id=0, 
    use_fields=true, fields=0x1522240078a0)
    at /test/10.11_opt/storage/spider/spd_db_conn.cc:7742
[Current thread is 1 (Thread 0x152265c47700 (LWP 1308466))]
(gdb) bt
#0  0x0000152265b4ec61 in spider_db_open_item_field (item_field=<optimized out>, spider=<optimized out>, str=0x152224062650, alias=<optimized out>, alias_length=<optimized out>, dbton_id=0, use_fields=true, fields=0x1522240078a0) at /test/10.11_opt/storage/spider/spd_db_conn.cc:7742
#1  0x0000152265bae7ca in spider_db_mbase_util::open_item_func (this=0x152265bfcae0 <spider_db_mysql_utility>, item_func=0x152224010de0, spider=0x15222404b5c0, str=0x152224062650, alias=0x0, alias_length=0, use_fields=true, fields=0x1522240078a0) at /test/10.11_opt/storage/spider/spd_db_mysql.cc:5727
#2  0x0000152265bc0f47 in spider_mbase_handler::append_list_item_select (this=0x1522240625f0, select=<optimized out>, str=0x152224062650, alias=0x0, alias_length=0, use_fields=true, fields=0x1522240078a0) at /test/10.11_opt/storage/spider/spd_db_mysql.cc:15555
#3  0x0000152265bc46f8 in spider_group_by_handler::init_scan (this=0x55886577d760) at /test/10.11_opt/storage/spider/spd_group_by_handler.cc:1301
#4  0x0000558862e2267d in Pushdown_query::execute (this=0x1522240142b8, join=join@entry=0x152224012088) at /test/10.11_opt/sql/group_by_handler.cc:49
#5  0x0000558862e045d5 in do_select (procedure=<optimized out>, join=0x152224012088) at /test/10.11_opt/sql/sql_select.cc:21206
#6  JOIN::exec_inner (this=0x152224012088) at /test/10.11_opt/sql/sql_select.cc:4812
#7  0x0000558862e04f68 in JOIN::exec (this=this@entry=0x152224012088) at /test/10.11_opt/sql/sql_select.cc:4590
#8  0x0000558862e03171 in mysql_select (thd=0x152224000c58, tables=0x152224010f60, fields=@0x152224010a68: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x152224010ec8, last = 0x152224010ec8, elements = 1}, <No data fields>}, conds=0x0, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=<optimized out>, result=0x152224012060, unit=0x152224004cd0, select_lex=0x1522240107c8) at /test/10.11_opt/sql/sql_select.cc:5070
#9  0x0000558862e038b7 in handle_select (thd=thd@entry=0x152224000c58, lex=lex@entry=0x152224004bf8, result=result@entry=0x152224012060, setup_tables_done_option=setup_tables_done_option@entry=0) at /test/10.11_opt/sql/sql_select.cc:581
#10 0x0000558862d855b1 in execute_sqlcom_select (thd=0x152224000c58, all_tables=0x152224010f60) at /test/10.11_opt/sql/sql_parse.cc:6261
#11 0x0000558862d931f8 in mysql_execute_command (thd=0x152224000c58, is_called_from_prepared_stmt=<optimized out>) at /test/10.11_opt/sql/sql_parse.cc:3945
#12 0x0000558862d807b5 in mysql_parse (rawbuf=<optimized out>, length=<optimized out>, parser_state=<optimized out>, thd=0x152224000c58) at /test/10.11_opt/sql/sql_parse.cc:8035
#13 mysql_parse (thd=0x152224000c58, rawbuf=<optimized out>, length=<optimized out>, parser_state=<optimized out>) at /test/10.11_opt/sql/sql_parse.cc:7957
#14 0x0000558862d8c2ca in dispatch_command (command=COM_QUERY, thd=0x152224000c58, packet=<optimized out>, packet_length=<optimized out>, blocking=<optimized out>) at /test/10.11_opt/sql/sql_class.h:1339
#15 0x0000558862d8e1f2 in do_command (thd=0x152224000c58, blocking=blocking@entry=true) at /test/10.11_opt/sql/sql_parse.cc:1407
#16 0x0000558862ea646f in do_handle_one_connection (connect=<optimized out>, connect@entry=0x558865a647e8, put_in_cache=put_in_cache@entry=true) at /test/10.11_opt/sql/sql_connect.cc:1418
#17 0x0000558862ea674d in handle_one_connection (arg=0x558865a647e8) at /test/10.11_opt/sql/sql_connect.cc:1312
#18 0x000015227ee8a609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#19 0x000015227ea76133 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

10.11.0 bc563f1a4b0b38de3b41fd0f0d3d8b7f1aacbd8b (Debug)

Core was generated by `/test/MD190822-mariadb-10.11.0-linux-x86_64-dbg/bin/mysqld --no-defaults --core'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  spider_db_open_item_field (item_field=item_field@entry=0x1456200141e8, 
    spider=spider@entry=0x1456200610f0, str=str@entry=0x14562009b3c0, 
    alias=alias@entry=0x0, alias_length=alias_length@entry=0, 
    dbton_id=dbton_id@entry=0, use_fields=true, fields=0x1456200cd580)
    at /test/10.11_dbg/storage/spider/spd_db_conn.cc:7742
[Current thread is 1 (Thread 0x1456740ad700 (LWP 1308530))]
(gdb) bt
#0  spider_db_open_item_field (item_field=item_field@entry=0x1456200141e8, spider=spider@entry=0x1456200610f0, str=str@entry=0x14562009b3c0, alias=alias@entry=0x0, alias_length=alias_length@entry=0, dbton_id=dbton_id@entry=0, use_fields=true, fields=0x1456200cd580) at /test/10.11_dbg/storage/spider/spd_db_conn.cc:7742
#1  0x000014566810965a in spider_db_print_item_type (item=item@entry=0x1456200141e8, field=field@entry=0x0, spider=spider@entry=0x1456200610f0, str=str@entry=0x14562009b3c0, alias=alias@entry=0x0, alias_length=alias_length@entry=0, dbton_id=0, use_fields=true, fields=0x1456200cd580) at /test/10.11_dbg/storage/spider/spd_db_conn.cc:7388
#2  0x0000145668192ed2 in spider_db_mbase_util::open_item_func (this=0x1456681f9150 <spider_db_mysql_utility>, item_func=0x145620014300, spider=0x1456200610f0, str=0x14562009b3c0, alias=0x0, alias_length=0, use_fields=true, fields=0x1456200cd580) at /test/10.11_dbg/storage/spider/spd_db_mysql.cc:5727
#3  0x0000145668108081 in spider_db_open_item_func (item_func=item_func@entry=0x145620014300, spider=spider@entry=0x1456200610f0, str=str@entry=0x14562009b3c0, alias=alias@entry=0x0, alias_length=alias_length@entry=0, dbton_id=dbton_id@entry=0, use_fields=true, fields=0x1456200cd580) at /test/10.11_dbg/storage/spider/spd_db_conn.cc:7548
#4  0x00001456681095d9 in spider_db_print_item_type (item=item@entry=0x145620014300, field=field@entry=0x0, spider=0x1456200610f0, str=str@entry=0x14562009b3c0, alias=alias@entry=0x0, alias_length=alias_length@entry=0, dbton_id=0, use_fields=true, fields=0x1456200cd580) at /test/10.11_dbg/storage/spider/spd_db_conn.cc:7379
#5  0x00001456681acf1d in spider_mbase_handler::append_list_item_select (this=this@entry=0x14562009b360, select=select@entry=0x145620015940, str=str@entry=0x14562009b3c0, alias=alias@entry=0x0, alias_length=alias_length@entry=0, use_fields=use_fields@entry=true, fields=0x1456200cd580) at /test/10.11_dbg/storage/spider/spd_db_mysql.cc:15555
#6  0x00001456681ad024 in spider_mbase_handler::append_list_item_select_part (this=0x14562009b360, select=0x145620015940, alias=0x0, alias_length=0, use_fields=<optimized out>, fields=0x1456200cd580, sql_type=1) at /test/10.11_dbg/storage/spider/spd_db_mysql.cc:15526
#7  0x00001456681b2e2c in spider_group_by_handler::init_scan (this=0x1456200e5c00) at /test/10.11_dbg/storage/spider/spd_group_by_handler.cc:1301
#8  0x0000559c99916685 in Pushdown_query::execute (this=0x1456200178e8, join=join@entry=0x1456200155a8) at /test/10.11_dbg/sql/group_by_handler.cc:49
#9  0x0000559c998e9399 in do_select (procedure=<optimized out>, join=0x1456200155a8) at /test/10.11_dbg/sql/sql_select.cc:21206
#10 JOIN::exec_inner (this=this@entry=0x1456200155a8) at /test/10.11_dbg/sql/sql_select.cc:4812
#11 0x0000559c998e9e28 in JOIN::exec (this=this@entry=0x1456200155a8) at /test/10.11_dbg/sql/sql_select.cc:4590
#12 0x0000559c998e7bac in mysql_select (thd=thd@entry=0x145620000db8, tables=0x145620014480, fields=@0x145620013f88: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x1456200143e8, last = 0x1456200143e8, elements = 1}, <No data fields>}, conds=0x0, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=2164525824, result=0x145620015580, unit=0x145620004ff0, select_lex=0x145620013ce8) at /test/10.11_dbg/sql/sql_select.cc:5070
#13 0x0000559c998e83a2 in handle_select (thd=thd@entry=0x145620000db8, lex=lex@entry=0x145620004f18, result=result@entry=0x145620015580, setup_tables_done_option=setup_tables_done_option@entry=0) at /test/10.11_dbg/sql/sql_select.cc:581
#14 0x0000559c998525a6 in execute_sqlcom_select (thd=thd@entry=0x145620000db8, all_tables=0x145620014480) at /test/10.11_dbg/sql/sql_parse.cc:6261
#15 0x0000559c9985e8c7 in mysql_execute_command (thd=thd@entry=0x145620000db8, is_called_from_prepared_stmt=is_called_from_prepared_stmt@entry=false) at /test/10.11_dbg/sql/sql_parse.cc:3945
#16 0x0000559c9984c882 in mysql_parse (thd=thd@entry=0x145620000db8, rawbuf=<optimized out>, length=<optimized out>, parser_state=parser_state@entry=0x1456740ac330) at /test/10.11_dbg/sql/sql_parse.cc:8035
#17 0x0000559c99859e6a in dispatch_command (command=command@entry=COM_QUERY, thd=thd@entry=0x145620000db8, packet=packet@entry=0x14562000b6e9 "", packet_length=packet_length@entry=38, blocking=blocking@entry=true) at /test/10.11_dbg/sql/sql_class.h:1339
#18 0x0000559c9985c574 in do_command (thd=0x145620000db8, blocking=blocking@entry=true) at /test/10.11_dbg/sql/sql_parse.cc:1407
#19 0x0000559c999be1da in do_handle_one_connection (connect=<optimized out>, connect@entry=0x559c9bbe0038, put_in_cache=put_in_cache@entry=true) at /test/10.11_dbg/sql/sql_connect.cc:1418
#20 0x0000559c999be6e3 in handle_one_connection (arg=0x559c9bbe0038) at /test/10.11_dbg/sql/sql_connect.cc:1312
#21 0x000014568d527609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#22 0x000014568d113133 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Bug confirmed present in:
MariaDB: 10.4.27 (dbg), 10.4.27 (opt), 10.5.18 (dbg), 10.5.18 (opt), 10.6.10 (dbg), 10.6.10 (opt), 10.7.6 (dbg), 10.7.6 (opt), 10.8.5 (dbg), 10.8.5 (opt), 10.9.2 (dbg), 10.9.2 (opt), 10.10.2 (dbg), 10.10.2 (opt), 10.11.0 (dbg), 10.11.0 (opt)

Bug (or feature/syntax) confirmed not present in:
MySQL: 5.5.62 (dbg), 5.5.62 (opt), 5.6.51 (dbg), 5.6.51 (opt), 5.7.38 (dbg), 5.7.38 (opt), 8.0.29 (dbg), 8.0.29 (opt)



 Comments   
Comment by Roel Van de Paar [ 2022-10-01 ]

Additional testcase which leads to a slightly different stack/UniqueID (10.5+ only, table creation fails in 10.4+, possible regression):

INSTALL PLUGIN Spider SONAME 'ha_spider.so';
CREATE USER Spider@localhost IDENTIFIED BY 'PWD0';
CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET '../socket.sock',DATABASE 'test',user 'Spider',PASSWORD 'PWD0');
CREATE TABLE t (c INT);
CREATE TABLE t0 (f INT,s DATE,e DATE,PERIOD FOR p (s,e),UNIQUE (f,p WITHOUT OVERLAPS)) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"' WITH SYSTEM VERSIONING PARTITION BY SYSTEM_TIME;
SELECT TRIM(LEADING''FROM s) FROM t0;

Leads to:

10.11.0 6ebdd3013a18b01dbecec76b870810329eb76586 (Optimized)

Core was generated by `/test/MD190922-mariadb-10.11.0-linux-x86_64-opt/bin/mysqld --no-defaults --core'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x000014e424312cf1 in spider_db_open_item_field (
    item_field=<optimized out>, spider=<optimized out>, str=0x14e3d009b0e0, 
    alias=<optimized out>, alias_length=<optimized out>, dbton_id=0, 
    use_fields=true, fields=0x14e3d0007970)
    at /test/10.11_opt/storage/spider/spd_db_conn.cc:7748
[Current thread is 1 (Thread 0x14e43805b700 (LWP 1483970))]
(gdb) bt
#0  0x000014e424312cf1 in spider_db_open_item_field (item_field=<optimized out>, spider=<optimized out>, str=0x14e3d009b0e0, alias=<optimized out>, alias_length=<optimized out>, dbton_id=0, use_fields=true, fields=0x14e3d0007970) at /test/10.11_opt/storage/spider/spd_db_conn.cc:7748
#1  0x000014e424371453 in spider_db_mbase_util::open_item_func (this=0x14e4243c0ae0 <spider_db_mysql_utility>, item_func=0x14e3d009e1c8, spider=0x14e3d003ffa0, str=<optimized out>, alias=0x0, alias_length=0, use_fields=true, fields=0x14e3d0007970) at /test/10.11_opt/storage/spider/spd_db_mysql.cc:6612
#2  0x000014e42436bef1 in spider_mbase_handler::append_item_type_part (sql_type=1, fields=<optimized out>, use_fields=<optimized out>, alias_length=<optimized out>, alias=<optimized out>, item=<optimized out>, this=0x14e3d009b080) at /test/10.11_opt/storage/spider/spd_db_mysql.cc:15419
#3  spider_mbase_handler::append_item_type_part (this=<optimized out>, item=<optimized out>, alias=<optimized out>, alias_length=<optimized out>, use_fields=<optimized out>, fields=<optimized out>, sql_type=1) at /test/10.11_opt/storage/spider/spd_db_mysql.cc:15399
#4  0x000014e424388807 in spider_group_by_handler::init_scan (this=0x14e3d00a18a0) at /test/10.11_opt/storage/spider/spd_group_by_handler.cc:1318
#5  0x000055655a28c27d in Pushdown_query::execute (this=0x14e3d0014700, join=join@entry=0x14e3d0012238) at /test/10.11_opt/sql/group_by_handler.cc:49
#6  0x000055655a26e175 in do_select (procedure=<optimized out>, join=0x14e3d0012238) at /test/10.11_opt/sql/sql_select.cc:21207
#7  JOIN::exec_inner (this=0x14e3d0012238) at /test/10.11_opt/sql/sql_select.cc:4813
#8  0x000055655a26eb08 in JOIN::exec (this=this@entry=0x14e3d0012238) at /test/10.11_opt/sql/sql_select.cc:4591
#9  0x000055655a26cd11 in mysql_select (thd=0x14e3d0000c58, tables=0x14e3d0011058, fields=@0x14e3d0010b78: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x14e3d0010fd0, last = 0x14e3d0010fd0, elements = 1}, <No data fields>}, conds=0x0, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=<optimized out>, result=0x14e3d0012210, unit=0x14e3d0004cd0, select_lex=0x14e3d00108d8) at /test/10.11_opt/sql/sql_select.cc:5071
#10 0x000055655a26d457 in handle_select (thd=thd@entry=0x14e3d0000c58, lex=lex@entry=0x14e3d0004bf8, result=result@entry=0x14e3d0012210, setup_tables_done_option=setup_tables_done_option@entry=0) at /test/10.11_opt/sql/sql_select.cc:582
#11 0x000055655a1ef051 in execute_sqlcom_select (thd=0x14e3d0000c58, all_tables=0x14e3d0011058) at /test/10.11_opt/sql/sql_parse.cc:6261
#12 0x000055655a1fcd48 in mysql_execute_command (thd=0x14e3d0000c58, is_called_from_prepared_stmt=<optimized out>) at /test/10.11_opt/sql/sql_parse.cc:3945
#13 0x000055655a1ea205 in mysql_parse (rawbuf=<optimized out>, length=<optimized out>, parser_state=<optimized out>, thd=0x14e3d0000c58) at /test/10.11_opt/sql/sql_parse.cc:8037
#14 mysql_parse (thd=0x14e3d0000c58, rawbuf=<optimized out>, length=<optimized out>, parser_state=<optimized out>) at /test/10.11_opt/sql/sql_parse.cc:7959
#15 0x000055655a1f5d6a in dispatch_command (command=COM_QUERY, thd=0x14e3d0000c58, packet=<optimized out>, packet_length=<optimized out>, blocking=<optimized out>) at /test/10.11_opt/sql/sql_class.h:1345
#16 0x000055655a1f7cb2 in do_command (thd=0x14e3d0000c58, blocking=blocking@entry=true) at /test/10.11_opt/sql/sql_parse.cc:1407
#17 0x000055655a31117f in do_handle_one_connection (connect=<optimized out>, connect@entry=0x55655d9b43a8, put_in_cache=put_in_cache@entry=true) at /test/10.11_opt/sql/sql_connect.cc:1416
#18 0x000055655a31145d in handle_one_connection (arg=0x55655d9b43a8) at /test/10.11_opt/sql/sql_connect.cc:1318
#19 0x000014e451ab5609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#20 0x000014e4516a1133 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Bug confirmed present in:
MariaDB: 10.5.18 (dbg), 10.5.18 (opt), 10.6.10 (dbg), 10.6.10 (opt), 10.7.6 (dbg), 10.7.6 (opt), 10.8.5 (dbg), 10.8.5 (opt), 10.9.3 (dbg), 10.9.3 (opt), 10.10.2 (dbg), 10.10.2 (opt), 10.11.0 (dbg), 10.11.0 (opt)

Bug (or feature/syntax) confirmed not present in:
MariaDB: 10.4.27 (dbg), 10.4.27 (opt)

Comment by Roel Van de Paar [ 2022-11-29 ]

Neither testcase produces any errors on an UB+ASAN build, nor do these crash on the given testcases.

Comment by Roel Van de Paar [ 2022-11-29 ]

MTR testcase, also updated to work with latest 10.11 (re user privileges)

--source include/have_innodb.inc
--let $SOCKET=`SELECT @@global.socket`
INSTALL PLUGIN spider SONAME 'ha_spider.so';
CREATE USER spider@localhost IDENTIFIED BY 'PWD1';
GRANT ALL ON test.* TO spider@localhost;
eval CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS(SOCKET "$SOCKET",DATABASE 'test',USER 'spider',PASSWORD 'PWD1');
CREATE TABLE t(c INT) ENGINE=InnoDB;
CREATE TABLE b(d INT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"';
SELECT TRIM(LEADING 'c' FROM d) FROM b;

This crashes 10.11.2 936436ef437c73911c18854a8ce8dad1216331b8 debug as of build from today.

Comment by Nayuta Yanagisawa (Inactive) [ 2022-11-29 ]

A MTR test case with cleanup:

--echo #
--echo # MDEV-29447 SIGSEGV in spider_db_open_item_field and SIGSEGV spider_db_print_item_type, on SELECT
--echo #
 
--disable_query_log
--disable_result_log
--source ../../t/test_init.inc
--enable_result_log
--enable_query_log
 
--connection child2_1
CREATE DATABASE auto_test_remote;
USE auto_test_remote;
eval CREATE TABLE tbl_a (
    a INT
) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
 
--connection master_1
CREATE DATABASE auto_test_local;
USE auto_test_local;
eval CREATE TABLE tbl_a (
    a INT
) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a", srv "s_2_1"';
 
SELECT TRIM(LEADING 'c' FROM a) FROM tbl_a;
 
--connection child2_1
DROP DATABASE auto_test_remote;
 
--connection master_1
DROP DATABASE auto_test_local;
 
--disable_query_log
--disable_result_log
--source ../t/test_deinit.inc
--enable_query_log
--enable_result_log

The bug is also reproducible on 10.3.

Comment by Yuchen Pei [ 2022-12-23 ]

The function spider_db_print_item_type walks the AST of an item, and may rebuild the query string str somehow.

It is called in multiple occasions, including when the spider group by handler is created (spider_create_group_by_handler), and indirectly when it builds and executes the query in spider_group_by_handler::init_scan, through spider_db_handler::append_list_item_select_part. The problem is that the function seems to serve very different purposes depending on whether str is null. In the call of spider_db_print_item_type during handler creation, str is null, and in the call during init_scan, str is the query string.

When the item is of ITEM_FUNC type, spider_db_print_item_type delegates to spider_db_mbase_util::open_item_func(), which is a monster function[1]. It may further walk the item down to its arguments.

[1] https://jira.mariadb.org/browse/MDEV-26285

When the item is of ITEM_FIELD type, it delegates to spider_db_open_item_field.

What happens in this testcase is, the function is ltrim, with a string ('c') and a field ('tbl_a.a') arguments. When spider_db_print_item_type is called during handler creation, it is supposed to populate the fields, which happens when spider_db_open_item_field is called with a null str. But because str is null, spider_db_mbase_util::open_item_func() decides not to descend into the arguments of the func item and call spider_db_open_item_field, so the fields are empty. Then, when spider_db_print_item_type is called again during init_scan, str is not null, and spider_db_mbase_util::open_item_func() walks down to the field argument, calling spider_db_open_item_field with a non-null str, causing the latter to access the invalid fields.

Why does spider_db_mbase_util::open_item_func() not continue walking the AST of the item if str is null? Shall we invert this behaviour? That requires further investigation...

The string variable with the poor name str acting as a flag makes the code rather unreadable, thus some refactoring in this regard would be nice.

Comment by Yuchen Pei [ 2022-12-23 ]

The commit 3836098c29ef1b7ff9d5fbde99b690eab73a0df1 in MDEV-26285 refactors spider_db_mbase_util::open_item_func() by splitting it into two parts, check_item_func and print_item_func:

  int error = check_item_func(item_func, spider, alias,
    alias_length, use_fields, fields);
  if (error)
    DBUG_RETURN(error);
  if (!str)
    DBUG_RETURN(0);
 
  DBUG_RETURN(print_item_func(item_func, spider, str, alias,
    alias_length, use_fields, fields));

It nicely handles null and non-null str}}s in two separate functions. Where it is null, inside {{check_item_func, it descends into the arguments, which fixes the problem in this ticket. Indeed, the testcase passes at commit 3836098c29ef1b7ff9d5fbde99b690eab73a0df1 and fails at its parent commit.

So the problem is reduced to adapting that commit (based on version 10.6.4) to the current 10.3 onwards.

Comment by Yuchen Pei [ 2023-01-03 ]

serg Assigning you to review because you seemed to be the reviewer of MDEV-26285. Here's the patch:

10.3: https://github.com/MariaDB/server/commit/dcd69cbd19a
This is the patch for the current 10.3. Different versions require patches with minor differences.

Comment by Yuchen Pei [ 2023-01-24 ]

The review is taking place on the maria-developers mailing list:

https://lists.launchpad.net/maria-developers/msg13283.html

Comment by Yuchen Pei [ 2023-01-24 ]

As I was going through the review comments, I noticed that the commit breaks spider.udf_pushdown... I thought I tested the commit against all spider tests but I don't remember as it was three weeks ago. It would be nice if buildbot could run all spider tests when any spider code is touched.

So I need to update the commit both according to the comments and to fix the testcase.

Update: That turned out to be a silly mistake: I forgot to check for Item_func::FUNC_SP in check_item_func().

Comment by Yuchen Pei [ 2023-01-30 ]

serg Thanks for the comments - I have replied in the thread in maria-developers[1]. The updated commit is https://github.com/MariaDB/server/commit/3ea2f6a5cd7. PTAL thanks.

[1] https://lists.launchpad.net/maria-developers/msg13287.html

Comment by Roel Van de Paar [ 2023-03-14 ]

I found an additional testcase with a similar but slightly different stack on optimized builds.

INSTALL PLUGIN Spider SONAME 'ha_spider.so';
CREATE USER Spider@localhost IDENTIFIED BY '';
CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET '../socket.sock',DATABASE 'test',user 'Spider',PASSWORD '');
CREATE TABLE t (c INT KEY,c1 BLOB,c2 TEXT) ENGINE=InnoDB;
SET collation_connection='utf16le_bin';
CREATE TABLE t1 (c INT,d BLOB) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"';
SELECT TRIM(c FROM '\1'),TRIM('\1' FROM c) FROM t1;

MTR:

--source include/have_innodb.inc
--let $SOCKET=`SELECT @@global.socket`
INSTALL PLUGIN Spider SONAME 'ha_spider.so';
CREATE USER Spider@localhost IDENTIFIED BY '';
GRANT ALL ON test.* TO Spider@localhost;
eval CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$SOCKET",DATABASE 'test',user 'Spider',PASSWORD '');
CREATE TABLE t (c INT KEY,c1 BLOB,c2 TEXT) ENGINE=InnoDB;
SET collation_connection='utf16le_bin';
CREATE TABLE t1 (c INT,d BLOB) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"';
SELECT TRIM(c FROM '\1'),TRIM('\1' FROM c) FROM t1;

Leads to:

11.0.1 f2dc4d4c10ac36a73b5c1eb765352d3aee808d66 (Optimized)

Core was generated by `/test/MD180223-mariadb-11.0.1-linux-x86_64-opt/bin/mariadbd --no-defaults --cor'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000150786b64cf8 in spider_db_open_item_field (
    item_field=<optimized out>, spider=<optimized out>, str=0x15071c0689f0, 
    alias=<optimized out>, alias_length=<optimized out>, dbton_id=0, 
    use_fields=true, fields=0x15071c028a40)
    at /test/11.0_opt/storage/spider/spd_db_conn.cc:7753
7753	            SPIDER_FIELD_HOLDER *field_holder = field_chain->field_holder;
[Current thread is 1 (Thread 0x15078c129640 (LWP 1248527))]
(gdb) bt
#0  0x0000150786b64cf8 in spider_db_open_item_field (item_field=<optimized out>, spider=<optimized out>, str=0x15071c0689f0, alias=<optimized out>, alias_length=<optimized out>, dbton_id=0, use_fields=true, fields=0x15071c028a40) at /test/11.0_opt/storage/spider/spd_db_conn.cc:7753
#1  0x0000150786bc2c94 in spider_db_mbase_util::open_item_func (this=<optimized out>, item_func=0x15071c012ee8, spider=<optimized out>, str=0x15071c0689f0, alias=<optimized out>, alias_length=<optimized out>, use_fields=<optimized out>, fields=<optimized out>) at /test/11.0_opt/storage/spider/spd_db_mysql.cc:6559
#2  0x0000150786bc46e2 in spider_db_mbase_util::open_item_func (this=0x150786c10ae0 <spider_db_mysql_utility>, item_func=0x15071c011190, spider=0x15071c042a80, str=0x15071c0689f0, alias=0x0, alias_length=0, use_fields=true, fields=0x15071c028a40) at /test/11.0_opt/storage/spider/spd_db_mysql.cc:5602
#3  0x0000150786bd6433 in spider_mbase_handler::append_list_item_select (this=0x15071c068990, select=<optimized out>, str=0x15071c0689f0, alias=0x0, alias_length=0, use_fields=true, fields=0x15071c028a40) at /test/11.0_opt/storage/spider/spd_db_mysql.cc:15399
#4  0x0000150786bd9b77 in spider_group_by_handler::init_scan (this=0x562c12366ba0) at /test/11.0_opt/storage/spider/spd_group_by_handler.cc:1301
#5  0x0000562c0e90395d in Pushdown_query::execute (this=0x15071c013fa0, join=join@entry=0x15071c012490) at /test/11.0_opt/sql/group_by_handler.cc:49
#6  0x0000562c0e8e54f7 in do_select (procedure=<optimized out>, join=0x15071c012490) at /test/11.0_opt/sql/sql_select.cc:22214
#7  JOIN::exec_inner (this=0x15071c012490) at /test/11.0_opt/sql/sql_select.cc:4888
#8  0x0000562c0e8e5f08 in JOIN::exec (this=this@entry=0x15071c012490) at /test/11.0_opt/sql/sql_select.cc:4666
#9  0x0000562c0e8e3fb1 in mysql_select (thd=0x15071c000c68, tables=0x15071c011300, fields=@0x15071c010af0: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x15071c010f90, last = 0x15071c011280, elements = 2}, <No data fields>}, conds=0x0, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=<optimized out>, result=0x15071c012468, unit=0x15071c004cf0, select_lex=0x15071c010838) at /test/11.0_opt/sql/sql_select.cc:5146
#10 0x0000562c0e8e46f4 in handle_select (thd=thd@entry=0x15071c000c68, lex=lex@entry=0x15071c004c18, result=result@entry=0x15071c012468, setup_tables_done_option=setup_tables_done_option@entry=0) at /test/11.0_opt/sql/sql_select.cc:608
#11 0x0000562c0e85dee5 in execute_sqlcom_select (thd=0x15071c000c68, all_tables=0x15071c011300) at /test/11.0_opt/sql/sql_parse.cc:6267
#12 0x0000562c0e86cf00 in mysql_execute_command (thd=0x15071c000c68, is_called_from_prepared_stmt=<optimized out>) at /test/11.0_opt/sql/sql_parse.cc:3949
#13 0x0000562c0e86e794 in mysql_parse (rawbuf=<optimized out>, length=<optimized out>, parser_state=<optimized out>, thd=0x15071c000c68) at /test/11.0_opt/sql/sql_parse.cc:8002
#14 mysql_parse (thd=0x15071c000c68, rawbuf=<optimized out>, length=<optimized out>, parser_state=<optimized out>) at /test/11.0_opt/sql/sql_parse.cc:7924
#15 0x0000562c0e870d72 in dispatch_command (command=COM_QUERY, thd=0x15071c000c68, packet=<optimized out>, packet_length=<optimized out>, blocking=<optimized out>) at /test/11.0_opt/sql/sql_parse.cc:1991
#16 0x0000562c0e872510 in do_command (thd=0x15071c000c68, blocking=blocking@entry=true) at /test/11.0_opt/sql/sql_parse.cc:1407
#17 0x0000562c0e98a717 in do_handle_one_connection (connect=<optimized out>, connect@entry=0x562c125dfdf8, put_in_cache=put_in_cache@entry=true) at /test/11.0_opt/sql/sql_connect.cc:1416
#18 0x0000562c0e98a9ed in handle_one_connection (arg=0x562c125dfdf8) at /test/11.0_opt/sql/sql_connect.cc:1318
#19 0x00001507b9236b43 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#20 0x00001507b92c8a00 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

Comment by Yuchen Pei [ 2023-06-14 ]

I have rebased the patch on the "current" 10.4-11.1 and included the test for MDEV-31338. Otherwise it is the same as the previous version.

Hi serg, ptal thanks: https://github.com/MariaDB/server/commit/f3aa4d0a215599344d6660878f963c75b4598f6b

Comment by Yuchen Pei [ 2023-06-21 ]

Thanks for the comments serg, ptal:

https://github.com/MariaDB/server/commit/a7f44662ca5

Comment by Yuchen Pei [ 2023-06-22 ]

New patch addressing the comment in https://lists.mariadb.org/hyperkitty/list/developers@lists.mariadb.org/message/BDN3FCX4KYO2BHTHZO24NBKXVSNRRTRY/

https://github.com/MariaDB/server/commit/c438f70d7b7

Comment by Sergei Golubchik [ 2023-06-22 ]

c438f70d7b7 is ok to push

Comment by Yuchen Pei [ 2023-06-27 ]

Thanks for the review. Pushed to 10.4. Marking as fixed.

Generated at Thu Feb 08 10:08:40 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.