diff options
Diffstat (limited to 'src/pl/plperl/plperl.c')
-rw-r--r-- | src/pl/plperl/plperl.c | 33 |
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); |