Skip to content

MDEV-37052 JSON_SCHEMA_VALID stack overflow handling errors #4135

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: 11.4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion sql/item_jsonfunc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);

#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_thread_stack_size, my_thread_stack_size, STACK_MIN_SIZE);
Expand Down
15 changes: 7 additions & 8 deletions sql/json_schema.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
#include "json_schema.h"
#include "json_schema_helper.h"
#include "pcre2.h"

#ifndef DBUG_OFF
int dbug_json_check_min_stack_requirement();
#endif

static HASH all_keywords_hash;

static Json_schema_keyword *create_json_schema_keyword(THD *thd)
Expand Down Expand Up @@ -2779,15 +2784,9 @@ bool create_object_and_handle_keyword(THD *thd, json_engine_t *je,
List<Json_schema_keyword> temporary_list;

DBUG_EXECUTE_IF("json_check_min_stack_requirement",
{
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);
});
dbug_json_check_min_stack_requirement(); return true;);
if (check_stack_overrun(thd, STACK_MIN_SIZE , NULL))
return 1;
return true;

while (json_scan_next(je)== 0 && je->stack_p >= level)
{
Expand Down
32 changes: 13 additions & 19 deletions sql/json_table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
#include "create_tmp_table.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)

class table_function_handlerton
Expand Down Expand Up @@ -104,13 +108,9 @@ int get_disallowed_table_deps_for_list(MEM_ROOT *mem_root,
List_iterator<TABLE_LIST> li(*join_list);

DBUG_EXECUTE_IF("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);
});
return -dbug_json_check_min_stack_requirement(););
if (check_stack_overrun(current_thd, STACK_MIN_SIZE , NULL))
return 1;
return -1;

while ((table= li++))
{
Expand Down Expand Up @@ -1345,29 +1345,27 @@ void Table_function_json_table::fix_after_pullout(TABLE_LIST *sql_table,
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;
List_iterator<TABLE_LIST> li(*join_list);

DBUG_EXECUTE_IF("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);
});
dbug_json_check_min_stack_requirement(); return true;);
if (check_stack_overrun(current_thd, STACK_MIN_SIZE , NULL))
return;
return true;
while ((table= li++))
{
table->dep_tables |= deps;
NESTED_JOIN *nested_join;
if ((nested_join= table->nested_join))
{
// 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;
}


Expand Down Expand Up @@ -1447,11 +1445,7 @@ table_map add_table_function_dependencies(List<TABLE_LIST> *join_list,
List_iterator<TABLE_LIST> li(*join_list);

DBUG_EXECUTE_IF("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 (dbug_json_check_min_stack_requirement()) return 0;);
if ((res=check_stack_overrun(current_thd, STACK_MIN_SIZE , NULL)))
return res;

Expand Down
16 changes: 0 additions & 16 deletions sql/sql_parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,20 +189,4 @@ check_table_access(THD *thd, privilege_t requirements,TABLE_LIST *tables,
{ return false; }
#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 */