MDEV-38368 Spider crash on fake loop detection variables

use my_safe_alloca() when the size might be large
This commit is contained in:
Sergei Golubchik 2025-12-18 11:01:29 +01:00
commit 64c9efbfa5
5 changed files with 73 additions and 7 deletions

View file

@ -0,0 +1 @@
# see .opt file

View file

@ -0,0 +1 @@
--loose_spider_disable_group_by_handler=0

View file

@ -0,0 +1,28 @@
install plugin spider soname 'ha_spider';
#
# MDEV-38368 Spider crash on fake loop detection variables
#
set global spider_same_server_link=1;
create server srv1
foreign data wrapper mysql
options (
host 'localhost',
user 'root',
socket '$MASTER_1_MYSOCK'
);
create table t1 (id int primary key, data varchar(255));
insert into t1 values (1, 'test'), (2, 'data');
create table st1 (id int primary key, data varchar(255)) engine=spider
comment='wrapper "mysql", srv "srv1", table "t1"';
set @`spider_lc_./test/st1` = concat('-', repeat('x', 900000), '-pid-tbl-');
select * from st1 limit 1;
id data
1 test
drop table st1, t1;
drop server srv1;
uninstall plugin spider;
Warnings:
Warning 1620 Plugin is busy and will be uninstalled on shutdown
drop tables mysql.spider_link_failed_log, mysql.spider_link_mon_servers, mysql.spider_tables, mysql.spider_table_crd, mysql.spider_table_position_for_recovery, mysql.spider_table_sts, mysql.spider_xa, mysql.spider_xa_failed_log, mysql.spider_xa_member;
truncate mysql.func;
# End of 10.6 tests

View file

@ -0,0 +1,36 @@
# group by hander doesn't matter here, let's not run this test twice
source include/have_group_by_handler.inc;
install plugin spider soname 'ha_spider';
--echo #
--echo # MDEV-38368 Spider crash on fake loop detection variables
--echo #
set global spider_same_server_link=1;
evalp create server srv1
foreign data wrapper mysql
options (
host 'localhost',
user 'root',
socket '$MASTER_1_MYSOCK'
);
create table t1 (id int primary key, data varchar(255));
insert into t1 values (1, 'test'), (2, 'data');
create table st1 (id int primary key, data varchar(255)) engine=spider
comment='wrapper "mysql", srv "srv1", table "t1"';
set @`spider_lc_./test/st1` = concat('-', repeat('x', 900000), '-pid-tbl-');
select * from st1 limit 1;
drop table st1, t1;
drop server srv1;
uninstall plugin spider;
drop tables mysql.spider_link_failed_log, mysql.spider_link_mon_servers, mysql.spider_tables, mysql.spider_table_crd, mysql.spider_table_position_for_recovery, mysql.spider_table_sts, mysql.spider_xa, mysql.spider_xa_failed_log, mysql.spider_xa_member;
truncate mysql.func;
--echo # End of 10.6 tests

View file

@ -1242,7 +1242,7 @@ int spider_conn_queue_loop_check(
*/
lex_str.length = top_share->path.length + SPIDER_SQL_LOP_CHK_PRM_PRF_LEN;
buf_sz = lex_str.length + 2;
loop_check_buf = (char *) my_alloca(buf_sz);
loop_check_buf = (char *) my_safe_alloca(buf_sz);
if (unlikely(!loop_check_buf))
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
@ -1309,7 +1309,7 @@ int spider_conn_queue_loop_check(
from_str.length = tmp_name - lex_str.str + 1;
}
}
my_afree(loop_check_buf);
my_safe_afree(loop_check_buf, buf_sz);
/*
construct loop_check_buf as <from_str>-<cur>-<to_str> e.g.
"-<mac>-<pid>-./test/t0--./test/t1-./test/t2", later used as
@ -1325,7 +1325,7 @@ int spider_conn_queue_loop_check(
to_str.str = path;
DBUG_PRINT("info", ("spider to=%s", to_str.str));
buf_sz = from_str.length + top_share->path.length + to_str.length + 3;
loop_check_buf = (char *) my_alloca(buf_sz);
loop_check_buf = (char *) my_safe_alloca(buf_sz);
if (unlikely(!loop_check_buf))
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
@ -1376,7 +1376,7 @@ int spider_conn_queue_loop_check(
lex_str.length + 2),
NullS)
)) {
my_afree(loop_check_buf);
my_safe_afree(loop_check_buf, buf_sz);
goto error_alloc_loop_check;
}
lcptr->flag = 0;
@ -1401,7 +1401,7 @@ int spider_conn_queue_loop_check(
(uchar *) to_str.str, to_str.length);
if (unlikely(my_hash_insert(&conn->loop_checked, (uchar *) lcptr)))
{
my_afree(loop_check_buf);
my_safe_afree(loop_check_buf, buf_sz);
goto error_hash_insert;
}
} else {
@ -1412,11 +1412,11 @@ int spider_conn_queue_loop_check(
lcptr->flag |= SPIDER_LOP_CHK_IGNORED;
}
pthread_mutex_unlock(&conn->loop_check_mutex);
my_afree(loop_check_buf);
my_safe_afree(loop_check_buf, buf_sz);
DBUG_PRINT("info", ("spider be sent or queued already"));
DBUG_RETURN(0);
}
my_afree(loop_check_buf);
my_safe_afree(loop_check_buf, buf_sz);
if ((error_num = spider_conn_queue_and_merge_loop_check(conn, lcptr)))
{