Fix for MXS-968

This commit adds a free() to null_auth_free_client_data, which plugs
the memory leak in maxinfo.

Also, this commit fixes some segfaults when multiple threads are
running status_row() or variable_row(). The functions use
statically allocated index variables, which often go out-of-bounds
in concurrent use. This fix changes the indexes to thread-specific
variables, with allocating and deallocating. This does seem to slow
the functions down somewhat.
This commit is contained in:
ekorh475
2016-11-18 11:30:02 +02:00
parent 5198c3e456
commit de4ea067cf
2 changed files with 37 additions and 18 deletions

View File

@ -150,4 +150,8 @@ null_auth_is_client_ssl_capable(DCB *dcb)
* @param dcb Request handler DCB connected to the client * @param dcb Request handler DCB connected to the client
*/ */
static void static void
null_auth_free_client_data(DCB *dcb) {} null_auth_free_client_data(DCB *dcb)
{
free(dcb->data);
dcb->data = NULL;
}

View File

@ -825,7 +825,6 @@ typedef struct
int index; int index;
char *like; char *like;
} VARCONTEXT; } VARCONTEXT;
/** /**
* Callback function to populate rows of the show variable * Callback function to populate rows of the show variable
* command * command
@ -836,7 +835,7 @@ typedef struct
static RESULT_ROW * static RESULT_ROW *
variable_row(RESULTSET *result, void *data) variable_row(RESULTSET *result, void *data)
{ {
VARCONTEXT *context = (VARCONTEXT *)data; VARCONTEXT *context = (VARCONTEXT *) data;
RESULT_ROW *row; RESULT_ROW *row;
char buf[80]; char buf[80];
@ -862,10 +861,14 @@ variable_row(RESULTSET *result, void *data)
(long)(*variables[context->index].func)()); (long)(*variables[context->index].func)());
resultset_row_set(row, 1, buf); resultset_row_set(row, 1, buf);
break; break;
default:
ss_dassert(!true);
} }
context->index++; context->index++;
return row; return row;
} }
// We only get to this point once all variables have been printed
free(data);
return NULL; return NULL;
} }
@ -911,15 +914,19 @@ RESULTSET *
maxinfo_variables() maxinfo_variables()
{ {
RESULTSET *result; RESULTSET *result;
static VARCONTEXT context; VARCONTEXT *context;
if ((context = malloc(sizeof(VARCONTEXT))) == NULL)
context.like = NULL;
context.index = 0;
if ((result = resultset_create(variable_row, &context)) == NULL)
{ {
return NULL; return NULL;
} }
context->like = NULL;
context->index = 0;
if ((result = resultset_create(variable_row, context)) == NULL)
{
free(context);
return NULL;
}
resultset_add_column(result, "Variable_name", 40, COL_TYPE_VARCHAR); resultset_add_column(result, "Variable_name", 40, COL_TYPE_VARCHAR);
resultset_add_column(result, "Value", 40, COL_TYPE_VARCHAR); resultset_add_column(result, "Value", 40, COL_TYPE_VARCHAR);
return result; return result;
@ -1140,10 +1147,14 @@ status_row(RESULTSET *result, void *data)
(long)(*status[context->index].func)()); (long)(*status[context->index].func)());
resultset_row_set(row, 1, buf); resultset_row_set(row, 1, buf);
break; break;
default:
ss_dassert(!true);
} }
context->index++; context->index++;
return row; return row;
} }
// We only get to this point once all status elements have been printed
free(data);
return NULL; return NULL;
} }
@ -1189,15 +1200,19 @@ RESULTSET *
maxinfo_status() maxinfo_status()
{ {
RESULTSET *result; RESULTSET *result;
static VARCONTEXT context; VARCONTEXT *context;
if ((context = malloc(sizeof(VARCONTEXT))) == NULL)
context.like = NULL;
context.index = 0;
if ((result = resultset_create(status_row, &context)) == NULL)
{ {
return NULL; return NULL;
} }
context->like = NULL;
context->index = 0;
if ((result = resultset_create(status_row, context)) == NULL)
{
free(context);
return NULL;
}
resultset_add_column(result, "Variable_name", 40, COL_TYPE_VARCHAR); resultset_add_column(result, "Variable_name", 40, COL_TYPE_VARCHAR);
resultset_add_column(result, "Value", 40, COL_TYPE_VARCHAR); resultset_add_column(result, "Value", 40, COL_TYPE_VARCHAR);
return result; return result;