Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b0b6196

Browse files
committed
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
1 parent b175bd5 commit b0b6196

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

contrib/spi/refint.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "commands/trigger.h"
1313
#include "executor/spi.h"
1414
#include "utils/builtins.h"
15+
#include "utils/memutils.h"
1516
#include "utils/rel.h"
1617

1718
PG_MODULE_MAGIC;
@@ -186,12 +187,13 @@ check_primary_key(PG_FUNCTION_ARGS)
186187

187188
/*
188189
* Remember that SPI_prepare places plan in current memory context -
189-
* so, we have to save plan in Top memory context for later use.
190+
* so, we have to save plan in TopMemoryContext for later use.
190191
*/
191192
if (SPI_keepplan(pplan))
192193
/* internal error */
193194
elog(ERROR, "check_primary_key: SPI_keepplan failed");
194-
plan->splan = (SPIPlanPtr *) malloc(sizeof(SPIPlanPtr));
195+
plan->splan = (SPIPlanPtr *) MemoryContextAlloc(TopMemoryContext,
196+
sizeof(SPIPlanPtr));
195197
*(plan->splan) = pplan;
196198
plan->nplans = 1;
197199
}
@@ -417,7 +419,8 @@ check_foreign_key(PG_FUNCTION_ARGS)
417419
char sql[8192];
418420
char **args2 = args;
419421

420-
plan->splan = (SPIPlanPtr *) malloc(nrefs * sizeof(SPIPlanPtr));
422+
plan->splan = (SPIPlanPtr *) MemoryContextAlloc(TopMemoryContext,
423+
nrefs * sizeof(SPIPlanPtr));
421424

422425
for (r = 0; r < nrefs; r++)
423426
{
@@ -614,6 +617,13 @@ find_plan(char *ident, EPlan **eplan, int *nplans)
614617
{
615618
EPlan *newp;
616619
int i;
620+
MemoryContext oldcontext;
621+
622+
/*
623+
* All allocations done for the plans need to happen in a session-safe
624+
* context.
625+
*/
626+
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
617627

618628
if (*nplans > 0)
619629
{
@@ -623,20 +633,24 @@ find_plan(char *ident, EPlan **eplan, int *nplans)
623633
break;
624634
}
625635
if (i != *nplans)
636+
{
637+
MemoryContextSwitchTo(oldcontext);
626638
return (*eplan + i);
627-
*eplan = (EPlan *) realloc(*eplan, (i + 1) * sizeof(EPlan));
639+
}
640+
*eplan = (EPlan *) repalloc(*eplan, (i + 1) * sizeof(EPlan));
628641
newp = *eplan + i;
629642
}
630643
else
631644
{
632-
newp = *eplan = (EPlan *) malloc(sizeof(EPlan));
645+
newp = *eplan = (EPlan *) palloc(sizeof(EPlan));
633646
(*nplans) = i = 0;
634647
}
635648

636-
newp->ident = strdup(ident);
649+
newp->ident = pstrdup(ident);
637650
newp->nplans = 0;
638651
newp->splan = NULL;
639652
(*nplans)++;
640653

654+
MemoryContextSwitchTo(oldcontext);
641655
return newp;
642656
}

0 commit comments

Comments
 (0)