On Thu, 16 Apr 2020 at 08:53, PG Bug reporting form
<noreply@postgresql.org> wrote:
> -- On CentOS 8, this bug is triggered with a hostname with 10+ characters.
> On MacOS 10.14.6, 19+ characters.
> INSERT INTO test.bug_report(hostname, device, mount, used_space_bytes,
> avail_space_bytes) VALUES ('12345678901234567890', 'devtmpfs', '/dev', 0,
> 6047076131313);commit;
> -- This should immediately crash the postgres service
--LOCATION: palloc, mcxt.c:934
Thanks for the report. This is certainly a bug.
I slightly simplified the test case to become:
drop table if exists crash;
CREATE TABLE crash (
id bigint generated by default as identity,
hostname varchar,
hostname_short varchar GENERATED ALWAYS AS (hostname) STORED,
device text,
mount text,
used_space_bytes bigint,
used_space_gb bigint GENERATED ALWAYS AS (used_space_bytes) STORED,
avail_space_bytes bigint,
avail_space_gb bigint GENERATED ALWAYS AS (avail_space_bytes) STORED,
inserted_dts timestamp with time zone NOT NULL DEFAULT clock_timestamp(),
inserted_by text NOT NULL DEFAULT session_user
);
INSERT INTO crash (hostname, device, mount, used_space_bytes,
avail_space_bytes) VALUES ('12345678901234567', 'devtmpfs', '/dev', 0,
6047076131313); -- no crash
INSERT INTO crash (hostname, device, mount, used_space_bytes,
avail_space_bytes) VALUES ('123456789012345678', 'devtmpfs', '/dev',
0, 6047076131313); -- crash
The crash occurs during ExecComputeStoredGenerated() when calculating
the hostname_short column. When we call ExecEvalExpr() for that
column, the eval function just returns the value of the Datum in the
"hostname" column, which is stored in "slot". This happens to be a
pointer into the tuple. This results in a crash because, later in that
function, we do ExecClearTuple(slot), which frees the memory for that
tuple.
I suppose it normally works because generally the calculation will be
using some SQL function which will return some calculated value which
is allocated, but in this case, we just return the pointer to the
memory in the tuple slot.
I'd say the fix should be to just datumCopy() the result of the
calculation. i.e the attached.
David