summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
authorSergei Petrunia <psergey@askmonty.org>2020-01-12 22:15:55 +0300
committerSergei Petrunia <psergey@askmonty.org>2020-01-12 22:15:55 +0300
commitd531b4ee3a9bcd89a2fa6b49a2207eaf966f53e3 (patch)
treefbdc8bb230c6d123f8b2484878acf234caf46810 /sql/sp_head.cc
parent9c3eca85141836548214e3c68f256b3868502509 (diff)
downloadmariadb-git-d531b4ee3a9bcd89a2fa6b49a2207eaf966f53e3.tar.gz
MDEV-21341: Fix UBSAN failures: Issue Sixbb-10.3-mdev21341-issueSix
(Variant #2 of the patch, which keeps the sp_head object inside the MEM_ROOT that sp_head object owns) (10.3 version of the fix, with handling for class sp_package) sp_head::operator new() and operator delete() were dereferencing sp_head* pointers to memory that didn't hold a valid sp_head object (it was not created/already destroyed). This caused UBSan to crash when looking up type information. Fixed by providing static sp_head::create() and sp_head::destroy() methods.
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r--sql/sp_head.cc77
1 files changed, 43 insertions, 34 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 360713fc452..af4316085b7 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -474,47 +474,39 @@ check_routine_name(const LEX_CSTRING *ident)
*
*/
-void *
-sp_head::operator new(size_t size) throw()
+sp_head *sp_head::create(sp_package *parent, const Sp_handler *handler)
{
- DBUG_ENTER("sp_head::operator new");
MEM_ROOT own_root;
+ init_sql_alloc(&own_root, "sp_head", MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC,
+ MYF(0));
sp_head *sp;
+ if (!(sp= new (&own_root) sp_head(&own_root, parent, handler)))
+ free_root(&own_root, MYF(0));
- init_sql_alloc(&own_root, "sp_head",
- MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC, MYF(0));
- sp= (sp_head *) alloc_root(&own_root, size);
- if (sp == NULL)
- DBUG_RETURN(NULL);
- sp->main_mem_root= own_root;
- DBUG_PRINT("info", ("mem_root %p", &sp->mem_root));
- DBUG_RETURN(sp);
+ return sp;
}
-void
-sp_head::operator delete(void *ptr, size_t size) throw()
-{
- DBUG_ENTER("sp_head::operator delete");
- MEM_ROOT own_root;
-
- if (ptr == NULL)
- DBUG_VOID_RETURN;
-
- sp_head *sp= (sp_head *) ptr;
- /* Make a copy of main_mem_root as free_root will free the sp */
- own_root= sp->main_mem_root;
- DBUG_PRINT("info", ("mem_root %p moved to %p",
- &sp->mem_root, &own_root));
- free_root(&own_root, MYF(0));
-
- DBUG_VOID_RETURN;
+void sp_head::destroy(sp_head *sp)
+{
+ if (sp)
+ {
+ /* Make a copy of main_mem_root as free_root will free the sp */
+ MEM_ROOT own_root= sp->main_mem_root;
+ delete sp;
+
+ DBUG_PRINT("info", ("mem_root 0x%lx moved to 0x%lx",
+ (ulong) &sp->mem_root, (ulong) &own_root));
+ free_root(&own_root, MYF(0));
+ }
}
-sp_head::sp_head(sp_package *parent, const Sp_handler *sph)
- :Query_arena(&main_mem_root, STMT_INITIALIZED_FOR_SP),
+sp_head::sp_head(MEM_ROOT *mem_root_arg, sp_package *parent,
+ const Sp_handler *sph)
+ :Query_arena(NULL, STMT_INITIALIZED_FOR_SP),
Database_qualified_name(&null_clex_str, &null_clex_str),
+ main_mem_root(*mem_root_arg),
m_parent(parent),
m_handler(sph),
m_flags(0),
@@ -545,6 +537,8 @@ sp_head::sp_head(sp_package *parent, const Sp_handler *sph)
m_pcont(new (&main_mem_root) sp_pcontext()),
m_cont_level(0)
{
+ mem_root= &main_mem_root;
+
m_first_instance= this;
m_first_free_instance= this;
m_last_cached_sp= this;
@@ -567,10 +561,25 @@ sp_head::sp_head(sp_package *parent, const Sp_handler *sph)
}
-sp_package::sp_package(LEX *top_level_lex,
+sp_package *sp_package::create(LEX *top_level_lex, const sp_name *name,
+ const Sp_handler *sph)
+{
+ MEM_ROOT own_root;
+ init_sql_alloc(&own_root, "sp_package", MEM_ROOT_BLOCK_SIZE,
+ MEM_ROOT_PREALLOC, MYF(0));
+ sp_package *sp;
+ if (!(sp= new (&own_root) sp_package(&own_root, top_level_lex, name, sph)))
+ free_root(&own_root, MYF(0));
+
+ return sp;
+}
+
+
+sp_package::sp_package(MEM_ROOT *mem_root_arg,
+ LEX *top_level_lex,
const sp_name *name,
const Sp_handler *sph)
- :sp_head(NULL, sph),
+ :sp_head(mem_root_arg, NULL, sph),
m_current_routine(NULL),
m_top_level_lex(top_level_lex),
m_rcontext(NULL),
@@ -588,7 +597,7 @@ sp_package::~sp_package()
m_routine_declarations.cleanup();
m_body= null_clex_str;
if (m_current_routine)
- delete m_current_routine->sphead;
+ sp_head::destroy(m_current_routine->sphead);
delete m_rcontext;
}
@@ -845,7 +854,7 @@ sp_head::~sp_head()
my_hash_free(&m_sptabs);
my_hash_free(&m_sroutines);
- delete m_next_cached_sp;
+ sp_head::destroy(m_next_cached_sp);
DBUG_VOID_RETURN;
}