summaryrefslogtreecommitdiff
path: root/src/pl/plperl/plperl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pl/plperl/plperl.c')
-rw-r--r--src/pl/plperl/plperl.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index f5738d0dc9..8c4e65936e 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -265,6 +265,7 @@ static plperl_proc_desc *compile_plperl_function(Oid fn_oid,
static SV *plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc, bool include_generated);
static SV *plperl_hash_from_datum(Datum attr);
+static void check_spi_usage_allowed(void);
static SV *plperl_ref_from_pg_array(Datum arg, Oid typid);
static SV *split_array(plperl_array_info *info, int first, int last, int nest);
static SV *make_array_ref(plperl_array_info *info, int first, int last);
@@ -1433,13 +1434,15 @@ plperl_sv_to_datum(SV *sv, Oid typid, int32 typmod,
char *
plperl_sv_to_literal(SV *sv, char *fqtypename)
{
- Datum str = CStringGetDatum(fqtypename);
- Oid typid = DirectFunctionCall1(regtypein, str);
+ Oid typid;
Oid typoutput;
Datum datum;
bool typisvarlena,
isnull;
+ check_spi_usage_allowed();
+
+ typid = DirectFunctionCall1(regtypein, CStringGetDatum(fqtypename));
if (!OidIsValid(typid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -3121,6 +3124,21 @@ check_spi_usage_allowed(void)
/* simple croak as we don't want to involve PostgreSQL code */
croak("SPI functions can not be used in END blocks");
}
+
+ /*
+ * Disallow SPI usage if we're not executing a fully-compiled plperl
+ * function. It might seem impossible to get here in that case, but there
+ * are cases where Perl will try to execute code during compilation. If
+ * we proceed we are likely to crash trying to dereference the prodesc
+ * pointer. Working around that might be possible, but it seems unwise
+ * because it'd allow code execution to happen while validating a
+ * function, which is undesirable.
+ */
+ if (current_call_data == NULL || current_call_data->prodesc == NULL)
+ {
+ /* simple croak as we don't want to involve PostgreSQL code */
+ croak("SPI functions can not be used during function compilation");
+ }
}
@@ -3241,6 +3259,8 @@ plperl_return_next(SV *sv)
{
MemoryContext oldcontext = CurrentMemoryContext;
+ check_spi_usage_allowed();
+
PG_TRY();
{
plperl_return_next_internal(sv);
@@ -3985,6 +4005,8 @@ plperl_spi_commit(void)
{
MemoryContext oldcontext = CurrentMemoryContext;
+ check_spi_usage_allowed();
+
PG_TRY();
{
SPI_commit();
@@ -4010,6 +4032,8 @@ plperl_spi_rollback(void)
{
MemoryContext oldcontext = CurrentMemoryContext;
+ check_spi_usage_allowed();
+
PG_TRY();
{
SPI_rollback();
@@ -4047,6 +4071,11 @@ plperl_util_elog(int level, SV *msg)
MemoryContext oldcontext = CurrentMemoryContext;
char *volatile cmsg = NULL;
+ /*
+ * We intentionally omit check_spi_usage_allowed() here, as this seems
+ * safe to allow even in the contexts that that function rejects.
+ */
+
PG_TRY();
{
cmsg = sv2cstr(msg);