summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2019-11-25 22:48:50 +0100
committerVladislav Vaintroub <wlad@mariadb.com>2019-11-28 10:48:09 +0100
commitba95c303e379b9f23289aaaffe18fb5d49ddf4a3 (patch)
tree88004462cb796a8660b85383b6389d3f4eea745c /mysys
parent584ffa02f1bef6931b3feb78559841ffe9c8600f (diff)
downloadmariadb-git-ba95c303e379b9f23289aaaffe18fb5d49ddf4a3.tar.gz
MDEV-21167 LF_PINS::stack_ends_here inaccurate, leading to alloca() larger than stack
Use my_thread_var::stack_ends_here inside lf_pinbox_real_free() for address where thread stack ends. Remove LF_PINS::stack_ends_here. It is not safe to assume that mysys_var that was used during pin allocation, remains correct during free. E.g with binlog group commit in Innodb, that frees pins for multiple Innodb transactions, it does not work correctly.
Diffstat (limited to 'mysys')
-rw-r--r--mysys/lf_alloc-pin.c14
1 files changed, 5 insertions, 9 deletions
diff --git a/mysys/lf_alloc-pin.c b/mysys/lf_alloc-pin.c
index 2a0ee7fddf9..b98684556c3 100644
--- a/mysys/lf_alloc-pin.c
+++ b/mysys/lf_alloc-pin.c
@@ -151,7 +151,6 @@ void lf_pinbox_destroy(LF_PINBOX *pinbox)
*/
LF_PINS *lf_pinbox_get_pins(LF_PINBOX *pinbox)
{
- struct st_my_thread_var *var;
uint32 pins, next, top_ver;
LF_PINS *el;
/*
@@ -194,12 +193,7 @@ LF_PINS *lf_pinbox_get_pins(LF_PINBOX *pinbox)
el->link= pins;
el->purgatory_count= 0;
el->pinbox= pinbox;
- var= my_thread_var;
- /*
- Threads that do not call my_thread_init() should still be
- able to use the LF_HASH.
- */
- el->stack_ends_here= (var ? & var->stack_ends_here : NULL);
+
return el;
}
@@ -335,16 +329,18 @@ static void lf_pinbox_real_free(LF_PINS *pins)
void *list;
void **addr= NULL;
void *first= NULL, *last= NULL;
+ struct st_my_thread_var *var= my_thread_var;
+ void *stack_ends_here= var ? var->stack_ends_here : NULL;
LF_PINBOX *pinbox= pins->pinbox;
npins= pinbox->pins_in_array+1;
#ifdef HAVE_ALLOCA
- if (pins->stack_ends_here != NULL)
+ if (stack_ends_here != NULL)
{
int alloca_size= sizeof(void *)*LF_PINBOX_PINS*npins;
/* create a sorted list of pinned addresses, to speed up searches */
- if (available_stack_size(&pinbox, *pins->stack_ends_here) >
+ if (available_stack_size(&pinbox, stack_ends_here) >
alloca_size + ALLOCA_SAFETY_MARGIN)
{
struct st_harvester hv;