Skip to content

Commit 9b103f8

Browse files
committed
Improve pglz_decompress's defenses against corrupt compressed data.
When processing a match tag, check to see if the claimed "off" is more than the distance back to the output buffer start. If it is, then the data is corrupt, and what's more we would fetch from outside the buffer boundaries and potentially incur a SIGSEGV. (Although the odds of that seem relatively low, given that "off" can't be more than 4K.) Back-patch to v13; before that, this function wasn't really trying to protect against bad data. Report and fix by Flavien Guedez. Discussion: https://postgr.es/m/01fc0593-e31e-463d-902c-dd43174acee2@oopacity.net
1 parent 7fb355d commit 9b103f8

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

src/common/pg_lzcompress.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -735,11 +735,15 @@ pglz_decompress(const char *source, int32 slen, char *dest,
735735

736736
/*
737737
* Check for corrupt data: if we fell off the end of the
738-
* source, or if we obtained off = 0, we have problems. (We
739-
* must check this, else we risk an infinite loop below in the
740-
* face of corrupt data.)
738+
* source, or if we obtained off = 0, or if off is more than
739+
* the distance back to the buffer start, we have problems.
740+
* (We must check for off = 0, else we risk an infinite loop
741+
* below in the face of corrupt data. Likewise, the upper
742+
* limit on off prevents accessing outside the buffer
743+
* boundaries.)
741744
*/
742-
if (unlikely(sp > srcend || off == 0))
745+
if (unlikely(sp > srcend || off == 0 ||
746+
off > (dp - (unsigned char *) dest)))
743747
return -1;
744748

745749
/*

0 commit comments

Comments
 (0)