Hi,
While attempting to isolate an error, I noticed that pg_restore segmentation faults on a corrupt file:
$ pg_restore -l clientname.small.dmp
Segmentation fault
The corrupt dump file was generated with pg_dump version Debian 11.10-1.pgdg90+ using (the -t seems to be the source of
corruption):
ssh -t example.com PGPASSWORD=passwordhere pg_dump --cluster 11/main -U clientname -d clientname_live --schema-only
-Fc> clientname.small.dmp
If it's helpful, I can supply the first 3500 bytes of the problem file, as that is enough to replicate the segmentation
fault.
I have replicated the issue both with debian package of postgresql 13.1 (Debian 13.1-1.pgdg100+1) and a fresh checkout
ofthe source (commit 920f853dc948b98a5dc96580c4ee011a302e33e4).
Here is a backtrace from the freshly compiled pg_restore:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7cbe2e3 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0 0x00007ffff7cbe2e3 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff7be5182 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007ffff7bd83dd in vsscanf () from /lib/x86_64-linux-gnu/libc.so.6
#3 0x00007ffff7bd2b94 in sscanf () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x0000555555564c10 in ReadToc (AH=AH@entry=0x5555555a0750)
at pg_backup_archiver.c:2578
#5 0x0000555555566668 in InitArchiveFmt_Custom (AH=AH@entry=0x5555555a0750)
at pg_backup_custom.c:185
#6 0x000055555555ea0d in _allocAH (FileSpec=0x7fffffffe5d1 "clientname.small.dmp",
fmt=archUnknown, compression=0, dosync=<optimized out>, mode=archModeRead,
setupWorkerPtr=0x55555555e170 <setupRestoreWorker>)
at pg_backup_archiver.c:2348
#7 0x0000555555559ecc in main (argc=3, argv=0x7fffffffe308)
at pg_restore.c:414
(gdb) fr 4
#4 0x0000555555564c10 in ReadToc (AH=AH@entry=0x5555555a0750)
at pg_backup_archiver.c:2578
2578 sscanf(tmp, "%u", &te->catalogId.tableoid);
(gdb) print tmp
$1 = 0x0
As you can see, tmp is NULL in this context because the previous ReadStr returned null, causing sscanf to segfault.
While this isn't a blocking issue for me (since pg was not the source of the corruption), I thought it might be nice
forthe next person to provide cleaner error handling, possibly this patch:
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index 1f82c6499b..4a07d43cc5 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -2575,6 +2575,8 @@ ReadToc(ArchiveHandle *AH)
if (AH->version >= K_VERS_1_8)
{
tmp = ReadStr(AH);
+ if (tmp == NULL)
+ fatal("Null catalog table oid -- perhaps a corrupt TOC");
sscanf(tmp, "%u", &te->catalogId.tableoid);
free(tmp);
}
thanks,
Jon Snell