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:
@@ -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);
|
||||||
|
@@ -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)
|
||||||
{
|
{
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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 */
|
||||||
|
Reference in New Issue
Block a user