aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2023-10-18 20:43:17 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2023-10-18 20:43:17 -0400
commit985ac5ce292ab084fe56b90528df6a2496f2c507 (patch)
tree302819b3f716c45b94fe69de7dc7d093580eb731 /src
parentb60e3ac7603dfae3f810418b1fb5856d9fc7a328 (diff)
downloadpostgresql-985ac5ce292ab084fe56b90528df6a2496f2c507.tar.gz
postgresql-985ac5ce292ab084fe56b90528df6a2496f2c507.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/common/pg_lzcompress.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/src/common/pg_lzcompress.c b/src/common/pg_lzcompress.c
index 9de5d5a0d43..ad3970c7a96 100644
--- a/src/common/pg_lzcompress.c
+++ b/src/common/pg_lzcompress.c
@@ -735,11 +735,15 @@ pglz_decompress(const char *source, int32 slen, char *dest,
/*
* Check for corrupt data: if we fell off the end of the
- * source, or if we obtained off = 0, we have problems. (We
- * must check this, else we risk an infinite loop below in the
- * face of corrupt data.)
+ * source, or if we obtained off = 0, or if off is more than
+ * the distance back to the buffer start, we have problems.
+ * (We must check for off = 0, else we risk an infinite loop
+ * below in the face of corrupt data. Likewise, the upper
+ * limit on off prevents accessing outside the buffer
+ * boundaries.)
*/
- if (unlikely(sp > srcend || off == 0))
+ if (unlikely(sp > srcend || off == 0 ||
+ off > (dp - (unsigned char *) dest)))
return -1;
/*