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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy