summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Paquier2020-01-08 01:02:55 +0000
committerMichael Paquier2020-01-08 01:02:55 +0000
commitb0b6196386681383b8f0cb76df4fd35178a7371e (patch)
tree80f5489cb66615a5e1556c23071d58d9da85fc5b
parentb175bd59fa54a90d21bc541f812643ac45281b98 (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.c26
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;
}