1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-37052 JSON_SCHEMA_VALID stack overflow handling errors

Since MDEV-33209 (09ea2dc788)
the the stack overflow errors are just injected instead of
frailer mechanisms to consume stack. These mechanims where
not carried forward to the JSON_TABLE or JSON_SCHEMA_VALID where
the pattern was the same.

add_extra_deps also no-longer recursively iterates in
out of stack conditions.

Tests performed in json_debug_nonembedded(_noasan).
This commit is contained in:
Daniel Black
2025-06-23 13:45:22 +10:00
parent 29c51ee1d7
commit dbeef00562
4 changed files with 21 additions and 44 deletions

View File

@@ -26,7 +26,7 @@ static bool check_overlaps(json_engine_t *, json_engine_t *, bool);
static int json_find_overlap_with_object(json_engine_t *, json_engine_t *, bool); static int json_find_overlap_with_object(json_engine_t *, json_engine_t *, bool);
#ifndef DBUG_OFF #ifndef DBUG_OFF
static int dbug_json_check_min_stack_requirement() int dbug_json_check_min_stack_requirement()
{ {
my_error(ER_STACK_OVERRUN_NEED_MORE, MYF(ME_FATAL), my_error(ER_STACK_OVERRUN_NEED_MORE, MYF(ME_FATAL),
my_thread_stack_size, my_thread_stack_size, STACK_MIN_SIZE); my_thread_stack_size, my_thread_stack_size, STACK_MIN_SIZE);

View File

@@ -21,6 +21,11 @@
#include "json_schema.h" #include "json_schema.h"
#include "json_schema_helper.h" #include "json_schema_helper.h"
#include "pcre2.h" #include "pcre2.h"
#ifndef DBUG_OFF
int dbug_json_check_min_stack_requirement();
#endif
static HASH all_keywords_hash; static HASH all_keywords_hash;
static Json_schema_keyword *create_json_schema_keyword(THD *thd) static Json_schema_keyword *create_json_schema_keyword(THD *thd)
@@ -2779,15 +2784,9 @@ bool create_object_and_handle_keyword(THD *thd, json_engine_t *je,
List<Json_schema_keyword> temporary_list; List<Json_schema_keyword> temporary_list;
DBUG_EXECUTE_IF("json_check_min_stack_requirement", DBUG_EXECUTE_IF("json_check_min_stack_requirement",
{ dbug_json_check_min_stack_requirement(); return true;);
long arbitrary_var;
long stack_used_up=
(available_stack_size(thd->thread_stack,
&arbitrary_var));
ALLOCATE_MEM_ON_STACK(my_thread_stack_size-stack_used_up-STACK_MIN_SIZE);
});
if (check_stack_overrun(thd, STACK_MIN_SIZE , NULL)) if (check_stack_overrun(thd, STACK_MIN_SIZE , NULL))
return 1; return true;
while (json_scan_next(je)== 0 && je->stack_p >= level) while (json_scan_next(je)== 0 && je->stack_p >= level)
{ {

View File

@@ -27,6 +27,10 @@
#include "create_tmp_table.h" #include "create_tmp_table.h"
#include "sql_parse.h" #include "sql_parse.h"
#ifndef DBUG_OFF
int dbug_json_check_min_stack_requirement();
#endif
#define HA_ERR_JSON_TABLE (HA_ERR_LAST+1) #define HA_ERR_JSON_TABLE (HA_ERR_LAST+1)
class table_function_handlerton class table_function_handlerton
@@ -104,13 +108,9 @@ int get_disallowed_table_deps_for_list(MEM_ROOT *mem_root,
List_iterator<TABLE_LIST> li(*join_list); List_iterator<TABLE_LIST> li(*join_list);
DBUG_EXECUTE_IF("json_check_min_stack_requirement", DBUG_EXECUTE_IF("json_check_min_stack_requirement",
{ return -dbug_json_check_min_stack_requirement(););
long arbitrary_var;
long stack_used_up= (available_stack_size(current_thd->thread_stack, &arbitrary_var));
ALLOCATE_MEM_ON_STACK(my_thread_stack_size-stack_used_up-STACK_MIN_SIZE);
});
if (check_stack_overrun(current_thd, STACK_MIN_SIZE , NULL)) if (check_stack_overrun(current_thd, STACK_MIN_SIZE , NULL))
return 1; return -1;
while ((table= li++)) while ((table= li++))
{ {
@@ -1345,19 +1345,15 @@ void Table_function_json_table::fix_after_pullout(TABLE_LIST *sql_table,
Recursively make all tables in the join_list also depend on deps. Recursively make all tables in the join_list also depend on deps.
*/ */
static void add_extra_deps(List<TABLE_LIST> *join_list, table_map deps) static bool add_extra_deps(List<TABLE_LIST> *join_list, table_map deps)
{ {
TABLE_LIST *table; TABLE_LIST *table;
List_iterator<TABLE_LIST> li(*join_list); List_iterator<TABLE_LIST> li(*join_list);
DBUG_EXECUTE_IF("json_check_min_stack_requirement", DBUG_EXECUTE_IF("json_check_min_stack_requirement",
{ dbug_json_check_min_stack_requirement(); return true;);
long arbitrary_var;
long stack_used_up= (available_stack_size(current_thd->thread_stack, &arbitrary_var));
ALLOCATE_MEM_ON_STACK(my_thread_stack_size-stack_used_up-STACK_MIN_SIZE);
});
if (check_stack_overrun(current_thd, STACK_MIN_SIZE , NULL)) if (check_stack_overrun(current_thd, STACK_MIN_SIZE , NULL))
return; return true;
while ((table= li++)) while ((table= li++))
{ {
table->dep_tables |= deps; table->dep_tables |= deps;
@@ -1365,9 +1361,11 @@ static void add_extra_deps(List<TABLE_LIST> *join_list, table_map deps)
if ((nested_join= table->nested_join)) if ((nested_join= table->nested_join))
{ {
// set the deps inside, too // set the deps inside, too
add_extra_deps(&nested_join->join_list, deps); if (add_extra_deps(&nested_join->join_list, deps))
return true;
} }
} }
return false;
} }
@@ -1447,11 +1445,7 @@ table_map add_table_function_dependencies(List<TABLE_LIST> *join_list,
List_iterator<TABLE_LIST> li(*join_list); List_iterator<TABLE_LIST> li(*join_list);
DBUG_EXECUTE_IF("json_check_min_stack_requirement", DBUG_EXECUTE_IF("json_check_min_stack_requirement",
{ if (dbug_json_check_min_stack_requirement()) return 0;);
long arbitrary_var;
long stack_used_up= (available_stack_size(current_thd->thread_stack, &arbitrary_var));
ALLOCATE_MEM_ON_STACK(my_thread_stack_size-stack_used_up-STACK_MIN_SIZE);
});
if ((res=check_stack_overrun(current_thd, STACK_MIN_SIZE , NULL))) if ((res=check_stack_overrun(current_thd, STACK_MIN_SIZE , NULL)))
return res; return res;

View File

@@ -189,20 +189,4 @@ check_table_access(THD *thd, privilege_t requirements,TABLE_LIST *tables,
{ return false; } { return false; }
#endif /*NO_EMBEDDED_ACCESS_CHECKS*/ #endif /*NO_EMBEDDED_ACCESS_CHECKS*/
/*
Allocating memory and *also* using it (reading and
writing from it) because some build instructions cause
compiler to optimize out stack_used_up. Since alloca()
here depends on stack_used_up, it doesnt get executed
correctly and causes json_debug_nonembedded to fail
( --error ER_STACK_OVERRUN_NEED_MORE does not occur).
*/
#define ALLOCATE_MEM_ON_STACK(A) do \
{ \
uchar *array= (uchar*)alloca(A); \
bzero(array, A); \
my_checksum(0, array, A); \
} while(0)
#endif /* SQL_PARSE_INCLUDED */ #endif /* SQL_PARSE_INCLUDED */