Thread
Commits
-
hstore_plperl: Add CHECK_FOR_INTERRUPTS() in reference-unwinding loop.
- c0f17b04d906 19 (unreleased) landed
- d65cf6f800f0 18 (unreleased) landed
- 60a1d712a472 16 (unreleased) landed
- 4fbbabb0a729 15 (unreleased) landed
- 4efef9d18e63 17 (unreleased) landed
- 1f6b2295f952 14 (unreleased) landed
-
jsonb_plperl, jsonb_plpython: Fix unguarded recursion and loops.
- e3b7a43fa9b6 18 (unreleased) landed
- da82fbb8f9a3 19 (unreleased) landed
- b0f3465b6f6a 16 (unreleased) landed
- a6f23c3ade0e 15 (unreleased) landed
- 639fff5118a8 14 (unreleased) landed
- 3df0b77558d7 17 (unreleased) landed
-
[PATCH] Fix segmentation fault and infinite loop in jsonb_{plperl,plpython}
Aleksander Alekseev <aleksander@tigerdata.com> — 2026-06-16T14:05:20Z
Hi, I discovered several bugs in jsonb_plperl and jsonb_plpython. The first bug causes a segfault when dealing with deeply nested JSONB values. As an example: ``` $ ./reproduce_stack_overflow.py plpython3u (depth=100000): SIGSEGV 2026-06-16 16:42:56.989 MSK [3209763] LOG: client backend (PID 3209810) was terminated by signal 11: Segmentation fault 2026-06-16 16:42:56.989 MSK [3209763] DETAIL: Failed process was running: SELECT py_deep(100000); plperl (depth=100000): SIGSEGV 2026-06-16 16:42:59.101 MSK [3209763] LOG: client backend (PID 3209827) was terminated by signal 11: Segmentation fault 2026-06-16 16:42:59.101 MSK [3209763] DETAIL: Failed process was running: SELECT perl_deep(100000); ``` The second bug affects only jsonb_plperl. It's possible to construct a Perl object with circular references which will cause SV_to_JsonbValue() to go into an infinite loop here: ``` while (SvROK(in)) in = SvRV(in); ``` The attached script reproduce_circular_ref.py reproduces the issue. Be careful if you decide to run it because the backend will become unresponsive to pg_cancel_backend() and you will be unable to stop the cluster in a standard way. I suggest fixing it by rewriting the while loop into a recursion with check_stack_depth() call. This will make the behavior consistent with jsonb_plpython. Patches are attached. Thoughts? -- Best regards, Aleksander Alekseev -
Re: [PATCH] Fix segmentation fault and infinite loop in jsonb_{plperl,plpython}
Tom Lane <tgl@sss.pgh.pa.us> — 2026-06-16T19:46:38Z
Aleksander Alekseev <aleksander@tigerdata.com> writes: > I discovered several bugs in jsonb_plperl and jsonb_plpython. Good catches, will take care of this. (I'm inclined to fold these into one patch, though.) regards, tom lane
-
Re: [PATCH] Fix segmentation fault and infinite loop in jsonb_{plperl,plpython}
Tom Lane <tgl@sss.pgh.pa.us> — 2026-06-16T20:03:28Z
Aleksander Alekseev <aleksander@tigerdata.com> writes: > The second bug affects only jsonb_plperl. It's possible to construct a > Perl object with circular references which will cause > SV_to_JsonbValue() to go into an infinite loop here: > while (SvROK(in)) > in = SvRV(in); > I suggest fixing it by rewriting the while loop into a recursion with > check_stack_depth() call. This will make the behavior consistent with > jsonb_plpython. Unfortunately, your 0002 is too cute for its own good. I tried it here, with a not-especially-new gcc compiling at -O2, and found that the tail recursion in SV_deref() is optimized into a loop. So the stack doesn't grow and we still have an uninterruptible loop. I don't immediately see a way to write that function so that the compiler is certain not to spot the tail recursion. Tricks like two mutually recursive functions might be seen through at sufficiently high -O levels. We could instead add a CHECK_FOR_INTERRUPTS, so that you can at least break out of the infinite loop. I'm not sure if the case is worth more effort than that. regards, tom lane
-
Re: [PATCH] Fix segmentation fault and infinite loop in jsonb_{plperl,plpython}
Aleksander Alekseev <aleksander@tigerdata.com> — 2026-06-16T21:03:12Z
Hi Tom, Thanks for taking a look. > > The second bug affects only jsonb_plperl. It's possible to construct a > > Perl object with circular references which will cause > > SV_to_JsonbValue() to go into an infinite loop here: > > > while (SvROK(in)) > > in = SvRV(in); > > > I suggest fixing it by rewriting the while loop into a recursion with > > check_stack_depth() call. This will make the behavior consistent with > > jsonb_plpython. > > Unfortunately, your 0002 is too cute for its own good. I tried it > here, with a not-especially-new gcc compiling at -O2, and found that > the tail recursion in SV_deref() is optimized into a loop. So the > stack doesn't grow and we still have an uninterruptible loop. That's funny :) > I don't immediately see a way to write that function so that the > compiler is certain not to spot the tail recursion. Tricks like > two mutually recursive functions might be seen through at > sufficiently high -O levels. > > We could instead add a CHECK_FOR_INTERRUPTS, so that you can at > least break out of the infinite loop. I'm not sure if the case > is worth more effort than that. Alternatively I could implement a check for the loops, if you feel like this is worth the effort. -- Best regards, Aleksander Alekseev
-
Re: [PATCH] Fix segmentation fault and infinite loop in jsonb_{plperl,plpython}
Tom Lane <tgl@sss.pgh.pa.us> — 2026-06-16T21:10:16Z
Aleksander Alekseev <aleksander@tigerdata.com> writes: >> We could instead add a CHECK_FOR_INTERRUPTS, so that you can at >> least break out of the infinite loop. I'm not sure if the case >> is worth more effort than that. > Alternatively I could implement a check for the loops, if you feel > like this is worth the effort. I thought about that, but I'm not sure how to build a bulletproof check at reasonable (ie, near zero) cost. We could detect the example case where an object refers directly to itself, by noticing that "in" doesn't change in one iteration. But I'm pretty sure it's possible to build reference loops involving two or more Perl objects, and those would fool such a check. regards, tom lane
-
Re: [PATCH] Fix segmentation fault and infinite loop in jsonb_{plperl,plpython}
Aleksander Alekseev <aleksander@tigerdata.com> — 2026-06-16T21:25:18Z
Hi, > > Alternatively I could implement a check for the loops, if you feel > > like this is worth the effort. > > I thought about that, but I'm not sure how to build a bulletproof > check at reasonable (ie, near zero) cost. We could detect the example > case where an object refers directly to itself, by noticing that "in" > doesn't change in one iteration. But I'm pretty sure it's possible to > build reference loops involving two or more Perl objects, and those > would fool such a check. I was thinking about depth-first search where we store our current path in a set. If the visited node is already in the set then the graph has loops. This is not exactly cheap but the complexity is proportional to the cost of the serialization so I think we should be fine. The good thing is that the user will get a sensible error message instead of an infinite loop. -- Best regards, Aleksander Alekseev
-
Re: [PATCH] Fix segmentation fault and infinite loop in jsonb_{plperl,plpython}
Tom Lane <tgl@sss.pgh.pa.us> — 2026-06-16T21:46:33Z
Aleksander Alekseev <aleksander@tigerdata.com> writes: >> I thought about that, but I'm not sure how to build a bulletproof >> check at reasonable (ie, near zero) cost. We could detect the example >> case where an object refers directly to itself, by noticing that "in" >> doesn't change in one iteration. But I'm pretty sure it's possible to >> build reference loops involving two or more Perl objects, and those >> would fool such a check. > I was thinking about depth-first search where we store our current > path in a set. If the visited node is already in the set then the > graph has loops. > This is not exactly cheap but the complexity is proportional to the > cost of the serialization so I think we should be fine. No, it'd be O(N^2) for an N-deep reference chain. Admittedly, realistic use-cases would never have more than a couple of layers of indirection. But this whole exercise is to guard against adversarial inputs, I think. I don't really want to add cycles and complexity to make our behavior a bit more friendly in cases that nobody is going to get into unless they are trying to break the database. regards, tom lane
-
Re: [PATCH] Fix segmentation fault and infinite loop in jsonb_{plperl,plpython}
Aleksander Alekseev <aleksander@tigerdata.com> — 2026-06-17T11:07:04Z
Hi Tom, Thanks for all your great feedback. > No, it'd be O(N^2) for an N-deep reference chain. Admittedly, > realistic use-cases would never have more than a couple of layers of > indirection. But this whole exercise is to guard against adversarial > inputs, I think. I don't really want to add cycles and complexity to > make our behavior a bit more friendly in cases that nobody is going > to get into unless they are trying to break the database. OK, that's fair enough. Here is the corrected patch. ``` =# SELECT perl_circular(); ^CCancel request sent ERROR: canceling statement due to user request CONTEXT: PL/Perl function "perl_circular" ``` -- Best regards, Aleksander Alekseev
-
Re: [PATCH] Fix segmentation fault and infinite loop in jsonb_{plperl,plpython}
Tom Lane <tgl@sss.pgh.pa.us> — 2026-06-17T15:05:30Z
Aleksander Alekseev <aleksander@tigerdata.com> writes: > OK, that's fair enough. Here is the corrected patch. Pushed with some comments added. regards, tom lane
-
Re: [PATCH] Fix segmentation fault and infinite loop in jsonb_{plperl,plpython}
Aleksander Alekseev <aleksander@tigerdata.com> — 2026-06-18T11:46:27Z
Hi Tom, > Pushed with some comments added. Thanks for applying the patch. I looked around and found the same bug in hstore_plperl: ``` =# CREATE EXTENSION IF NOT EXISTS hstore_plperl CASCADE; CREATE EXTENSION =# CREATE OR REPLACE FUNCTION hstore_circular() RETURNS hstore LANGUAGE plperl TRANSFORM FOR TYPE hstore AS $$ my $x; $x = \$x; return $x; $$; CREATE FUNCTION =# SELECT hstore_circular(); ^CCancel request sent ^CCancel request sent ^CCancel request sent ``` From what I can tell this is the last issue like this. Here is the patch. Would you like to merge it as well or will it be better to start a new thread for visibility? -- Best regards, Aleksander Alekseev
-
Re: [PATCH] Fix segmentation fault and infinite loop in jsonb_{plperl,plpython}
Tom Lane <tgl@sss.pgh.pa.us> — 2026-06-18T16:24:51Z
Aleksander Alekseev <aleksander@tigerdata.com> writes: > I looked around and found the same bug in hstore_plperl: D'oh, I should have spotted that myself. Pushed, thanks for noticing. regards, tom lane