Commit b0b61963 authored by Michael Paquier's avatar Michael Paquier

Remove dependency to system calls for memory allocation in refint

Failures in allocations could lead to crashes with NULL pointer
dereferences .  Memory context TopMemoryContext is used instead to keep
alive the plans allocated in the session.  A more specific context could
be used here, but this is left for later.

Reported-by: Jian Zhang
Author: Michael Paquier
Reviewed-by: Tom Lane, Andres Freund
Discussion: https://postgr.es/m/16190-70181c803641c3dc@postgresql.org
parent b175bd59
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "commands/trigger.h" #include "commands/trigger.h"
#include "executor/spi.h" #include "executor/spi.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/memutils.h"
#include "utils/rel.h" #include "utils/rel.h"
PG_MODULE_MAGIC; PG_MODULE_MAGIC;
...@@ -186,12 +187,13 @@ check_primary_key(PG_FUNCTION_ARGS) ...@@ -186,12 +187,13 @@ check_primary_key(PG_FUNCTION_ARGS)
/* /*
* Remember that SPI_prepare places plan in current memory context - * Remember that SPI_prepare places plan in current memory context -
* so, we have to save plan in Top memory context for later use. * so, we have to save plan in TopMemoryContext for later use.
*/ */
if (SPI_keepplan(pplan)) if (SPI_keepplan(pplan))
/* internal error */ /* internal error */
elog(ERROR, "check_primary_key: SPI_keepplan failed"); elog(ERROR, "check_primary_key: SPI_keepplan failed");
plan->splan = (SPIPlanPtr *) malloc(sizeof(SPIPlanPtr)); plan->splan = (SPIPlanPtr *) MemoryContextAlloc(TopMemoryContext,
sizeof(SPIPlanPtr));
*(plan->splan) = pplan; *(plan->splan) = pplan;
plan->nplans = 1; plan->nplans = 1;
} }
...@@ -417,7 +419,8 @@ check_foreign_key(PG_FUNCTION_ARGS) ...@@ -417,7 +419,8 @@ check_foreign_key(PG_FUNCTION_ARGS)
char sql[8192]; char sql[8192];
char **args2 = args; char **args2 = args;
plan->splan = (SPIPlanPtr *) malloc(nrefs * sizeof(SPIPlanPtr)); plan->splan = (SPIPlanPtr *) MemoryContextAlloc(TopMemoryContext,
nrefs * sizeof(SPIPlanPtr));
for (r = 0; r < nrefs; r++) for (r = 0; r < nrefs; r++)
{ {
...@@ -614,6 +617,13 @@ find_plan(char *ident, EPlan **eplan, int *nplans) ...@@ -614,6 +617,13 @@ find_plan(char *ident, EPlan **eplan, int *nplans)
{ {
EPlan *newp; EPlan *newp;
int i; int i;
MemoryContext oldcontext;
/*
* All allocations done for the plans need to happen in a session-safe
* context.
*/
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
if (*nplans > 0) if (*nplans > 0)
{ {
...@@ -623,20 +633,24 @@ find_plan(char *ident, EPlan **eplan, int *nplans) ...@@ -623,20 +633,24 @@ find_plan(char *ident, EPlan **eplan, int *nplans)
break; break;
} }
if (i != *nplans) if (i != *nplans)
{
MemoryContextSwitchTo(oldcontext);
return (*eplan + i); return (*eplan + i);
*eplan = (EPlan *) realloc(*eplan, (i + 1) * sizeof(EPlan)); }
*eplan = (EPlan *) repalloc(*eplan, (i + 1) * sizeof(EPlan));
newp = *eplan + i; newp = *eplan + i;
} }
else else
{ {
newp = *eplan = (EPlan *) malloc(sizeof(EPlan)); newp = *eplan = (EPlan *) palloc(sizeof(EPlan));
(*nplans) = i = 0; (*nplans) = i = 0;
} }
newp->ident = strdup(ident); newp->ident = pstrdup(ident);
newp->nplans = 0; newp->nplans = 0;
newp->splan = NULL; newp->splan = NULL;
(*nplans)++; (*nplans)++;
MemoryContextSwitchTo(oldcontext);
return newp; return newp;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment