diff options
author | Michael Paquier | 2020-01-08 01:02:55 +0000 |
---|---|---|
committer | Michael Paquier | 2020-01-08 01:02:55 +0000 |
commit | b0b6196386681383b8f0cb76df4fd35178a7371e (patch) | |
tree | 80f5489cb66615a5e1556c23071d58d9da85fc5b | |
parent | b175bd59fa54a90d21bc541f812643ac45281b98 (diff) |
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/[email protected]
-rw-r--r-- | contrib/spi/refint.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/contrib/spi/refint.c b/contrib/spi/refint.c index adf0490f853..6fbfef2b121 100644 --- a/contrib/spi/refint.c +++ b/contrib/spi/refint.c @@ -12,6 +12,7 @@ #include "commands/trigger.h" #include "executor/spi.h" #include "utils/builtins.h" +#include "utils/memutils.h" #include "utils/rel.h" PG_MODULE_MAGIC; @@ -186,12 +187,13 @@ check_primary_key(PG_FUNCTION_ARGS) /* * 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)) /* internal error */ 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->nplans = 1; } @@ -417,7 +419,8 @@ check_foreign_key(PG_FUNCTION_ARGS) char sql[8192]; char **args2 = args; - plan->splan = (SPIPlanPtr *) malloc(nrefs * sizeof(SPIPlanPtr)); + plan->splan = (SPIPlanPtr *) MemoryContextAlloc(TopMemoryContext, + nrefs * sizeof(SPIPlanPtr)); for (r = 0; r < nrefs; r++) { @@ -614,6 +617,13 @@ find_plan(char *ident, EPlan **eplan, int *nplans) { EPlan *newp; int i; + MemoryContext oldcontext; + + /* + * All allocations done for the plans need to happen in a session-safe + * context. + */ + oldcontext = MemoryContextSwitchTo(TopMemoryContext); if (*nplans > 0) { @@ -623,20 +633,24 @@ find_plan(char *ident, EPlan **eplan, int *nplans) break; } if (i != *nplans) + { + MemoryContextSwitchTo(oldcontext); return (*eplan + i); - *eplan = (EPlan *) realloc(*eplan, (i + 1) * sizeof(EPlan)); + } + *eplan = (EPlan *) repalloc(*eplan, (i + 1) * sizeof(EPlan)); newp = *eplan + i; } else { - newp = *eplan = (EPlan *) malloc(sizeof(EPlan)); + newp = *eplan = (EPlan *) palloc(sizeof(EPlan)); (*nplans) = i = 0; } - newp->ident = strdup(ident); + newp->ident = pstrdup(ident); newp->nplans = 0; newp->splan = NULL; (*nplans)++; + MemoryContextSwitchTo(oldcontext); return newp; } |