Hi, pg_waldump segfaults on a 58-byte record with a valid CRC. The attached script puts it in place of the first record of a fresh cluster's WAL. Reproduced on 15 to master (e75fcc9867f).
DecodeXLogRecord sums the block data, image and main data lengths into datatotal and checks it against the bytes left after the headers. datatotal is a uint32 and main_data_len alone can be UINT32_MAX, so the sum wraps to the remaining length and passes the check. The memcpy of the main data then reads ~4 GB past the record. 18992dc9d98 capped xl_tot_len, but the lengths inside the record are still summed in a uint32. The patch makes datatotal a uint64, and the record is rejected with "record with invalid length". There is no test, because the record needs a valid CRC, which 039_end_of_wal.pl can't build. I can add one if wanted. Best Regards, Iliia
#!/bin/sh # usage: make-segment.sh <bindir> <workdir> # initdb a fresh cluster and overwrite its first WAL record with record.bin # (58 bytes, CRC already valid, xl_prev = 0), then run pg_waldump on it. set -e B=$1; W=$2; HERE=$(cd "$(dirname "$0")" && pwd) "$B/initdb" -D "$W/data" >/dev/null mkdir -p "$W/wal" cp "$W/data/pg_wal/000000010000000000000001" "$W/wal/" dd if="$HERE/record.bin" of="$W/wal/000000010000000000000001" bs=1 seek=40 conv=notrunc 2>/dev/null cd "$W/wal" && "$B/pg_waldump" 000000010000000000000001
0001-Prevent-overflow-of-datatotal-in-DecodeXLogRecord.patch
Description: Binary data
record.bin
Description: application/macbinary
