[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#56247: inflate fails to reject invalid distance
From: |
Adler, Mark |
Subject: |
bug#56247: inflate fails to reject invalid distance |
Date: |
Mon, 27 Jun 2022 21:29:37 +0000 |
Paul,
gzip should reject invalid inflate input. The patch below does that.
The fact that pigz also doesn’t reject it is an independent bug in zlib’s
uncommonly-used inflateBack functions, fixed with this commit:
https://github.com/madler/zlib/commit/2333419cd76cb9ae5f15c9b240b16a2052b27691
Mark
On Jun 27, 2022, at 12:10 PM, Paul Eggert
<eggert@cs.ucla.edu<mailto:eggert@cs.ucla.edu>> wrote:
On 6/26/22 22:21, Young Mo Kang wrote:
I believe GNU gzip also needs to reject this file, since the file is not a
valid deflate format.
gzip is compatible with pigz here. It's not clear to me that gzip should be
pedantic and reject input that does not strictly conform to RFC 1952.
I'll cc this to Mark Adler in hopes that he has an opinion. Mark, if I
understand things correctly, the complaint is that the attached "compressed"
file does not conform to RFC 1952, but gzip and pigz do not complain about it.
You can see the original gzip bug report here:
https://bugs.gnu.org/56247
<bad-gzip-data>
--- inflate-orig.c 2022-01-03 10:16:30.000000000 -0800
+++ inflate.c 2022-06-27 14:01:42.000000000 -0700
@@ -153,8 +153,9 @@
"uch *slide;" and then malloc'ed in the latter case. The definition
must be in unzip.h, included above. */
/* unsigned wp; current position in slide */
+int fresh;
#define wp outcnt
-#define flush_output(w) (wp=(w),flush_window())
+#define flush_output(w) (fresh=0,wp=(w),flush_window())
/* Tables for deflate from PKZIP's appnote.txt. */
static unsigned border[] = { /* Order of the bit length code lengths */
@@ -572,6 +573,8 @@
NEEDBITS(e)
d = w - t->v.n - ((unsigned)b & mask_bits[e]);
DUMPBITS(e)
+ if (fresh && d >= w)
+ return 1;
Tracevv((stderr,"\\[%d,%d]", w-d, n));
/* do the copy */
@@ -954,6 +957,7 @@
wp = 0;
bk = 0;
bb = 0;
+ fresh = 1;
/* decompress until the last block */