From 5a2f9cf910225f97d7f4df8316c0d3da29cd11c2 Mon Sep 17 00:00:00 2001 From: Xing Guo Date: Tue, 23 Jun 2026 14:38:59 +0800 Subject: [PATCH v1] PL/Perl: Fix NULL deref for forged array A PL/Perl function returning a forged PostgreSQL::InServer::ARRAY object (e.g., an empty hash blessed as that class) could cause a segfault. This occurs because hv_fetch_string returns NULL pointer when the "array" key is missing, and the code previously dereferenced it without checking if the pointer itself was NULL. This commit adds a NULL check before dereferencing the result of hv_fetch_string, preventing the crash and properly returning an error. A test case is also included to prevent regressions. --- src/pl/plperl/expected/plperl_array.out | 9 +++++++++ src/pl/plperl/plperl.c | 2 +- src/pl/plperl/sql/plperl_array.sql | 9 +++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/pl/plperl/expected/plperl_array.out b/src/pl/plperl/expected/plperl_array.out index 260a55ea7e9..4bfaab733a9 100644 --- a/src/pl/plperl/expected/plperl_array.out +++ b/src/pl/plperl/expected/plperl_array.out @@ -274,3 +274,12 @@ select perl_setof_array('{{1}, {2}, {3}}'); {3} (3 rows) +-- Test NULL deref in get_perl_array_ref +CREATE OR REPLACE FUNCTION test_null_deref_crash() RETURNS integer[] AS $$ + my $h = {}; + bless $h, 'PostgreSQL::InServer::ARRAY'; + return $h; +$$ LANGUAGE plperl; +SELECT test_null_deref_crash(); +ERROR: could not get array reference from PostgreSQL::InServer::ARRAY object +CONTEXT: PL/Perl function "test_null_deref_crash" diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index c1f9b8932a3..9ddb81d42b9 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -1154,7 +1154,7 @@ get_perl_array_ref(SV *sv) HV *hv = (HV *) SvRV(sv); SV **sav = hv_fetch_string(hv, "array"); - if (*sav && SvOK(*sav) && SvROK(*sav) && + if (sav && *sav && SvOK(*sav) && SvROK(*sav) && SvTYPE(SvRV(*sav)) == SVt_PVAV) return *sav; diff --git a/src/pl/plperl/sql/plperl_array.sql b/src/pl/plperl/sql/plperl_array.sql index ca63b5db625..248cafef726 100644 --- a/src/pl/plperl/sql/plperl_array.sql +++ b/src/pl/plperl/sql/plperl_array.sql @@ -206,3 +206,12 @@ create or replace function perl_setof_array(integer[]) returns setof integer[] l $$; select perl_setof_array('{{1}, {2}, {3}}'); + +-- Test NULL deref in get_perl_array_ref +CREATE OR REPLACE FUNCTION test_null_deref_crash() RETURNS integer[] AS $$ + my $h = {}; + bless $h, 'PostgreSQL::InServer::ARRAY'; + return $h; +$$ LANGUAGE plperl; + +SELECT test_null_deref_crash(); -- 2.50.1 (Apple Git-155)