Thread: BUG #15578: Executing json_populate_recordset with an empty arraycauses a segmentation fault

BUG #15578: Executing json_populate_recordset with an empty arraycauses a segmentation fault

From
PG Bug reporting form
Date:
The following bug has been logged on the website:

Bug reference:      15578
Logged by:          Greg Keegan
Email address:      gregk@stoddarts.com.au
PostgreSQL version: 11.1
Operating system:   CentOS Linux release 7.1.1503 (Core)
Description:

When executing json_populate_recordset/jsonb_populate_recordset with an
empty array, a segmentation fault occurs and the server process is
terminated. The issue occurs regardless of the type used. In previous
versions this would return null.

Example:
CREATE TYPE test_type AS (amount numeric, description text);
SELECT * FROM json_populate_recordset(null::test_type,'[]');

Log:
2019-01-07 13:46:58.196 AEST [1847] LOG:  server process (PID 4341) was
terminated by signal 11: Segmentation fault
2019-01-07 13:46:58.196 AEST [1847] DETAIL:  Failed process was running:
SELECT * FROM json_populate_recordset(null::test_type,'[]');
2019-01-07 13:46:58.196 AEST [1847] LOG:  terminating any other active
server processes
2019-01-07 13:46:58.202 AEST [4213] WARNING:  terminating connection because
of crash of another server process
2019-01-07 13:46:58.202 AEST [4213] DETAIL:  The postmaster has commanded
this server process to roll back the current transaction and exit, because
another server process exited abnormally and possibly corrupted shared
memory.
2019-01-07 13:46:58.202 AEST [4213] HINT:  In a moment you should be able to
reconnect to the database and repeat your command.
2019-01-07 13:46:58.210 AEST [1847] LOG:  all server processes terminated;
reinitializing
2019-01-07 13:46:58.884 AEST [4374] LOG:  database system was interrupted;
last known up at 2019-01-07 13:42:07 AEST
2019-01-07 13:46:59.565 AEST [4374] LOG:  database system was not properly
shut down; automatic recovery in progress
2019-01-07 13:46:59.592 AEST [4374] LOG:  redo starts at 29/CD051528
2019-01-07 13:46:59.593 AEST [4374] LOG:  invalid record length at
29/CD069AD0: wanted 24, got 0
2019-01-07 13:46:59.593 AEST [4374] LOG:  redo done at 29/CD069A98
2019-01-07 13:46:59.593 AEST [4374] LOG:  last completed transaction was at
log time 2019-01-07 13:46:44.868687+10
2019-01-07 13:46:59.708 AEST [1847] LOG:  database system is ready to accept
connections


On Mon, Jan 07, 2019 at 03:52:26AM +0000, PG Bug reporting form wrote:
> When executing json_populate_recordset/jsonb_populate_recordset with an
> empty array, a segmentation fault occurs and the server process is
> terminated. The issue occurs regardless of the type used. In previous
> versions this would return null.

This has been already fixed by a recent commit, which will be released
with 11.2 in the next round of minor releases (see also 595220a which
applies to REL_11_STABLE):
commit: eba2ce17121f198316d050e71d8bd049a43783ba
author: Tom Lane <tgl@sss.pgh.pa.us>
date: Thu, 22 Nov 2018 15:14:01 -0500
committer: Tom Lane <tgl@sss.pgh.pa.us>
date: Thu, 22 Nov 2018 15:14:01 -0500
Fix another crash in json{b}_populate_recordset and
json{b}_to_recordset.

populate_recordset_worker() failed to consider the possibility that the
supplied JSON data contains no rows, so that update_cached_tupdesc never
got called.  This led to a null-pointer dereference since commit 9a5e8ed28;
before that it led to a bogus "set-valued function called in context
that cannot accept a set" error.  Fix by forcing the update to happen.

Per bug #15514.  Back-patch to v11 as 9a5e8ed28 was.  (If we were excited
about the bogus error, we could perhaps go back further, but it'd take more
work to figure out how to fix it in older branches.  Given the lack of
field complaints about that aspect, I'm not excited.)

Discussion: https://postgr.es/m/15514-59d5b4c4065b178b@postgresql.org
--
Michael

Attachment
=?utf-8?q?PG_Bug_reporting_form?= <noreply@postgresql.org> writes:
> When executing json_populate_recordset/jsonb_populate_recordset with an
> empty array, a segmentation fault occurs and the server process is
> terminated. The issue occurs regardless of the type used. In previous
> versions this would return null.
> Example:
> CREATE TYPE test_type AS (amount numeric, description text);
> SELECT * FROM json_populate_recordset(null::test_type,'[]');

Hm, this example works for me in HEAD and 11 branch tip, so I'm
guessing it was fixed by this commit:

https://git.postgresql.org/gitweb/?p=postgresql.git&a=commitdiff&h=595220a3a

That'll be out in 11.2, or you can apply the patch locally if
you're in a hurry.

            regards, tom lane