PostgreSQL Bugs

Collected from the PG bugs email list.

Bug ID16082
PG Version12.0
OSMicrosoft Windows [Version 10.0.18362.418]
Opened2019-10-26 07:46:25+00
Reported bycili
StatusNew

Body of first available message related to this bug follows.

The following bug has been logged on the website:

Bug reference:      16082
Logged by:          cili
Email address:      (redacted)
PostgreSQL version: 12.0
Operating system:   Microsoft Windows [Version 10.0.18362.418]
Description:        

The function pglz_decompress in src/common/pglz_decompress.c may refer
invalid data in the corrupted database file.
I show you two bad cases along with corrupted database file, and how to
make.

The first byte of TOAST structure is a control byte. If the LSB of control
byte is set, the 2nd byte is the length and the 3rd byte is an offset of
repeating bytes in dest block.
There is two case that they are valid for invalid data. In the case 1, it
reads an uninitialized data in the dest. In the case 2, it reads
uninitialized or out-of-bound data in the dest. They are invalid.
I'll show you the setup and one normal case, and then show two bad bug
cases.

Detail of case 1:
The first byte of TOAST structure in the corrupted database file is set
LSB.
The line 741 in pg_lzcompress.c read a byte from dp[-off] with off = 0, and
write to *dp.
It refers an uninitialized byte in the dest.

Detail of case 2:
The first byte of TOAST structure in the corrupted database file is not set
LSB, and the third byte such as the control byte in the second tag is set
LSB.
Similar to the case 2, the line 741 in pg_lzcompress.c read a byte from
dp[-off] with off > 0, and write to *dp.
It refers out-of-bound bytes in the dest.

Expected:
The program prevents the invalid accesses, and reports an error.

Examples:
= is an informal comment.
% is a CLI command in OS Shell.
# is a SQL command in SQL Shell.
%%% is a reminder.
*** is a instruction to corrupt the database.

===============================================
= [setup]
=   create database file.
=   insert data into database.
=   find the database filename. Then we modify the database file.
===============================================
% initdb testdb
% psql -d testdb
# CREATE TABLE test(id INTEGER, body BYTEA, PRIMARY KEY (id));
# INSERT INTO test values(1, convert_to(repeat('A', 32768), 'UTF8'));
# SELECT relfilenode from pg_class where relname like 'test';

 relfilenode
-------------
        16401

===============================================
= [normal case]
===============================================
# SELECT body from test;
\x41414141...

# \q

%%% Please remember the result of normal case.
%%% We modify the dabase file, and show two bad cases.

===============================================
= [bad case 1]
=   corrupt the databae file
===============================================
*** Edit the database file '16401' with case 1. Restart the PostgreSQL.
% psql -d testdb
# SELECT body from test;
\x000000...  ...0041

# \q

===============================================
= [bad case 2]
=   corrupt the databae file
===============================================

*** Edit the database file '16401' with case 2. Restart the PostgreSQL.
% psql -d testdb
# SELECT body from test;
\x410000...  ...0000
# \q

================================================
= example of database file '16401'
================================================
original:
00001E80   00 80 00 00 FE 41 0F 01 FF 0F 01 FF 0F 01 FF 0F

case 1:
00001E80   00 80 00 00 FD 0F FF FF 41 0F 01 FF 0F 01 FF 0F

case 2:
00001E80   00 80 00 00 FE 41 0F FF FF 0F 01 FF 0F 01 FF 0F

Messages

DateAuthorSubject
2019-10-26 07:46:25+00PG Bug reporting formBUG #16082: TOAST's pglz_decompress access to uninitialized data, if the database is corrupted.
2019-10-26 21:56:46+00Tomas VondraRe: BUG #16082: TOAST's pglz_decompress access to uninitialized data, if the database is corrupted.
2019-10-30 20:30:14+00Alvaro HerreraRe: BUG #16082: TOAST's pglz_decompress access to uninitialized data, if the database is corrupted.
2019-10-31 00:00:48+00Tomas VondraRe: BUG #16082: TOAST's pglz_decompress access to uninitialized data, if the database is corrupted.