Re: BUG #16369: Segmentation Faults and Data Corruption withGenerated Columns - Mailing list pgsql-bugs

From David Rowley
Subject Re: BUG #16369: Segmentation Faults and Data Corruption withGenerated Columns
Date
Msg-id CAApHDvr7xeMcfGRWQ0rxtagw7CKbjEcjPKfKQAU4KdEcZm6XkQ@mail.gmail.com
Whole thread Raw
In response to BUG #16369: Segmentation Faults and Data Corruption with Generated Columns  (PG Bug reporting form <noreply@postgresql.org>)
Responses Re: BUG #16369: Segmentation Faults and Data Corruption with Generated Columns
List pgsql-bugs
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

Attachment

pgsql-bugs by date:

Previous
From: Tomas Vondra
Date:
Subject: Re: BUG #16352: Data corruption in few tables
Next
From: Tom Lane
Date:
Subject: Re: BUG #16369: Segmentation Faults and Data Corruption with Generated Columns