]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Do a more thorough check of the state for every stream call.
authorMark Adler <madler@alumni.caltech.edu>
Tue, 25 Oct 2016 03:11:41 +0000 (20:11 -0700)
committerHans Kristian Rosbach <hk-git@circlestorm.org>
Wed, 1 Feb 2017 11:22:21 +0000 (12:22 +0100)
This verifies that the state has been initialized, that it is the
expected type of state, deflate or inflate, and that at least the
first several bytes of the internal state have not been clobbered.

deflate.c
inflate.c
inflate.h

index 33c660335354df0aea0be37e85ec7cbb73da5ef7..4c0e55a48fd19a256f6dd49ccd03c2f544fee493 100644 (file)
--- a/deflate.c
+++ b/deflate.c
@@ -68,6 +68,7 @@ const char deflate_copyright[] = " deflate 1.2.8.f Copyright 1995-2013 Jean-loup
 typedef block_state (*compress_func) (deflate_state *s, int flush);
 /* Compression function. Returns the block state after the call. */
 
+static int deflateStateCheck      (z_stream *strm);
 static block_state deflate_stored (deflate_state *s, int flush);
 block_state deflate_fast         (deflate_state *s, int flush);
 block_state deflate_quick        (deflate_state *s, int flush);
@@ -218,6 +219,7 @@ int ZEXPORT deflateInit2_(z_stream *strm, int level, int method, int windowBits,
         return Z_MEM_ERROR;
     strm->state = (struct internal_state *)s;
     s->strm = strm;
+    s->status = INIT_STATE;     /* to pass state test in deflateReset() */
 
     s->wrap = wrap;
     s->gzhead = NULL;
@@ -269,6 +271,26 @@ int ZEXPORT deflateInit2_(z_stream *strm, int level, int method, int windowBits,
     return deflateReset(strm);
 }
 
+/* =========================================================================
+ * Check for a valid deflate stream state. Return 0 if ok, 1 if not.
+ */
+static int deflateStateCheck (z_stream *strm) {
+    deflate_state *s;
+    if (strm == NULL ||
+        strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
+        return 1;
+    s = strm->state;
+    if (s == NULL || s->strm != strm || (s->status != INIT_STATE &&
+                                           s->status != EXTRA_STATE &&
+                                           s->status != NAME_STATE &&
+                                           s->status != COMMENT_STATE &&
+                                           s->status != HCRC_STATE &&
+                                           s->status != BUSY_STATE &&
+                                           s->status != FINISH_STATE))
+        return 1;
+    return 0;
+}
+
 /* ========================================================================= */
 int ZEXPORT deflateSetDictionary(z_stream *strm, const unsigned char *dictionary, unsigned int dictLength) {
     deflate_state *s;
@@ -277,7 +299,7 @@ int ZEXPORT deflateSetDictionary(z_stream *strm, const unsigned char *dictionary
     uint32_t avail;
     const unsigned char *next;
 
-    if (strm == NULL || strm->state == NULL || dictionary == NULL)
+    if (deflateStateCheck(strm) || dictionary == NULL)
         return Z_STREAM_ERROR;
     s = strm->state;
     wrap = s->wrap;
@@ -331,7 +353,7 @@ int ZEXPORT deflateSetDictionary(z_stream *strm, const unsigned char *dictionary
 int ZEXPORT deflateResetKeep(z_stream *strm) {
     deflate_state *s;
 
-    if (strm == NULL || strm->state == NULL || strm->zalloc == NULL || strm->zfree == NULL) {
+    if (deflateStateCheck(strm)) {
         return Z_STREAM_ERROR;
     }
 
@@ -371,9 +393,7 @@ int ZEXPORT deflateReset(z_stream *strm) {
 
 /* ========================================================================= */
 int ZEXPORT deflateSetHeader(z_stream *strm, gz_headerp head) {
-    if (strm == NULL || strm->state == NULL)
-        return Z_STREAM_ERROR;
-    if (strm->state->wrap != 2)
+    if (deflateStateCheck(strm) || strm->state->wrap != 2)
         return Z_STREAM_ERROR;
     strm->state->gzhead = head;
     return Z_OK;
@@ -381,7 +401,7 @@ int ZEXPORT deflateSetHeader(z_stream *strm, gz_headerp head) {
 
 /* ========================================================================= */
 int ZEXPORT deflatePending(z_stream *strm, uint32_t *pending, int *bits) {
-    if (strm == NULL || strm->state == NULL)
+    if (deflateStateCheck(strm))
         return Z_STREAM_ERROR;
     if (pending != NULL)
         *pending = strm->state->pending;
@@ -395,7 +415,7 @@ int ZEXPORT deflatePrime(z_stream *strm, int bits, int value) {
     deflate_state *s;
     int put;
 
-    if (strm == NULL || strm->state == NULL)
+    if (deflateStateCheck(strm))
         return Z_STREAM_ERROR;
     s = strm->state;
     if ((unsigned char *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
@@ -419,7 +439,7 @@ int ZEXPORT deflateParams(z_stream *strm, int level, int strategy) {
     compress_func func;
     int err = Z_OK;
 
-    if (strm == NULL || strm->state == NULL)
+    if (deflateStateCheck(strm))
         return Z_STREAM_ERROR;
     s = strm->state;
 
@@ -451,7 +471,7 @@ int ZEXPORT deflateParams(z_stream *strm, int level, int strategy) {
 int ZEXPORT deflateTune(z_stream *strm, int good_length, int max_lazy, int nice_length, int max_chain) {
     deflate_state *s;
 
-    if (strm == NULL || strm->state == NULL)
+    if (deflateStateCheck(strm))
         return Z_STREAM_ERROR;
     s = strm->state;
     s->good_match = (unsigned int)good_length;
@@ -487,7 +507,7 @@ unsigned long ZEXPORT deflateBound(z_stream *strm, unsigned long sourceLen) {
     complen = sourceLen + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
 
     /* if can't get parameters, return conservative bound plus zlib wrapper */
-    if (strm == NULL || strm->state == NULL)
+    if (deflateStateCheck(strm))
         return complen + 6;
 
     /* compute wrapper length */
@@ -576,7 +596,7 @@ int ZEXPORT deflate(z_stream *strm, int flush) {
     int old_flush; /* value of flush param for previous deflate call */
     deflate_state *s;
 
-    if (strm == NULL || strm->state == NULL || flush > Z_BLOCK || flush < 0) {
+    if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) {
         return Z_STREAM_ERROR;
     }
     s = strm->state;
@@ -882,19 +902,10 @@ int ZEXPORT deflate(z_stream *strm, int flush) {
 int ZEXPORT deflateEnd(z_stream *strm) {
     int status;
 
-    if (strm == NULL || strm->state == NULL)
+    if (deflateStateCheck(strm))
         return Z_STREAM_ERROR;
 
     status = strm->state->status;
-    if (status != INIT_STATE &&
-        status != EXTRA_STATE &&
-        status != NAME_STATE &&
-        status != COMMENT_STATE &&
-        status != HCRC_STATE &&
-        status != BUSY_STATE &&
-        status != FINISH_STATE) {
-      return Z_STREAM_ERROR;
-    }
 
     /* Deallocate in reverse order of allocations: */
     TRY_FREE(strm, strm->state->pending_buf);
@@ -916,7 +927,7 @@ int ZEXPORT deflateCopy(z_stream *dest, z_stream *source) {
     deflate_state *ss;
     uint16_t *overlay;
 
-    if (source == NULL || dest == NULL || source->state == NULL) {
+    if (deflateStateCheck(source) || dest == NULL) {
         return Z_STREAM_ERROR;
     }
 
index f0a341501d2f64a1d3d37f6d9577d7091f512359..298479f860b29f96da7fab40457f20a193b5f9d7 100644 (file)
--- a/inflate.c
+++ b/inflate.c
@@ -92,6 +92,7 @@
 #endif
 
 /* function prototypes */
+static int inflateStateCheck(z_stream *strm);
 static void fixedtables(struct inflate_state *state);
 static int updatewindow(z_stream *strm, const unsigned char *end, uint32_t copy);
 #ifdef BUILDFIXED
@@ -99,10 +100,20 @@ static int updatewindow(z_stream *strm, const unsigned char *end, uint32_t copy)
 #endif
 static uint32_t syncsearch(uint32_t *have, const unsigned char *buf, uint32_t len);
 
+static int inflateStateCheck(z_stream *strm) {
+    struct inflate_state *state;
+    if (strm == NULL || strm->zalloc == NULL || strm->zfree == NULL)
+        return 1;
+    state = (struct inflate_state *)strm->state;
+    if (state == NULL || state->strm != strm || state->mode < HEAD || state->mode > SYNC)
+        return 1;
+    return 0;
+}
+
 int ZEXPORT inflateResetKeep(z_stream *strm) {
     struct inflate_state *state;
 
-    if (strm == NULL || strm->state == NULL)
+    if (inflateStateCheck(strm))
         return Z_STREAM_ERROR;
     state = (struct inflate_state *)strm->state;
     strm->total_in = strm->total_out = state->total = 0;
@@ -126,7 +137,7 @@ int ZEXPORT inflateResetKeep(z_stream *strm) {
 int ZEXPORT inflateReset(z_stream *strm) {
     struct inflate_state *state;
 
-    if (strm == NULL || strm->state == NULL)
+    if (inflateStateCheck(strm))
         return Z_STREAM_ERROR;
     state = (struct inflate_state *)strm->state;
     state->wsize = 0;
@@ -140,7 +151,7 @@ int ZEXPORT inflateReset2(z_stream *strm, int windowBits) {
     struct inflate_state *state;
 
     /* get the state */
-    if (strm == NULL || strm->state == NULL)
+    if (inflateStateCheck(strm))
         return Z_STREAM_ERROR;
     state = (struct inflate_state *)strm->state;
 
@@ -190,7 +201,9 @@ int ZEXPORT inflateInit2_(z_stream *strm, int windowBits, const char *version, i
         return Z_MEM_ERROR;
     Tracev((stderr, "inflate: allocated\n"));
     strm->state = (struct internal_state *)state;
+    state->strm = strm;
     state->window = NULL;
+    state->mode = HEAD;     /* to pass state test in inflateReset2() */
     ret = inflateReset2(strm, windowBits);
     if (ret != Z_OK) {
         ZFREE(strm, state);
@@ -206,7 +219,7 @@ int ZEXPORT inflateInit_(z_stream *strm, const char *version, int stream_size) {
 int ZEXPORT inflatePrime(z_stream *strm, int bits, int value) {
     struct inflate_state *state;
 
-    if (strm == NULL || strm->state == NULL)
+    if (inflateStateCheck(strm))
         return Z_STREAM_ERROR;
     state = (struct inflate_state *)strm->state;
     if (bits < 0) {
@@ -592,7 +605,7 @@ int ZEXPORT inflate(z_stream *strm, int flush) {
     static const uint16_t order[19] = /* permutation of code lengths */
         {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
 
-    if (strm == NULL || strm->state == NULL || strm->next_out == NULL ||
+    if (inflateStateCheck(strm) || strm->next_out == NULL ||
         (strm->next_in == NULL && strm->avail_in != 0))
         return Z_STREAM_ERROR;
 
@@ -1228,7 +1241,7 @@ int ZEXPORT inflate(z_stream *strm, int flush) {
 
 int ZEXPORT inflateEnd(z_stream *strm) {
     struct inflate_state *state;
-    if (strm == NULL || strm->state == NULL || strm->zfree == NULL)
+    if (inflateStateCheck(strm))
         return Z_STREAM_ERROR;
     state = (struct inflate_state *)strm->state;
     if (state->window != NULL)
@@ -1243,7 +1256,7 @@ int ZEXPORT inflateGetDictionary(z_stream *strm, unsigned char *dictionary, unsi
     struct inflate_state *state;
 
     /* check state */
-    if (strm == NULL || strm->state == NULL)
+    if (inflateStateCheck(strm))
         return Z_STREAM_ERROR;
     state = (struct inflate_state *)strm->state;
 
@@ -1263,7 +1276,7 @@ int ZEXPORT inflateSetDictionary(z_stream *strm, const unsigned char *dictionary
     int ret;
 
     /* check state */
-    if (strm == NULL || strm->state == NULL)
+    if (inflateStateCheck(strm))
         return Z_STREAM_ERROR;
     state = (struct inflate_state *)strm->state;
     if (state->wrap != 0 && state->mode != DICT)
@@ -1293,7 +1306,7 @@ int ZEXPORT inflateGetHeader(z_stream *strm, gz_headerp head) {
     struct inflate_state *state;
 
     /* check state */
-    if (strm == NULL || strm->state == NULL)
+    if (inflateStateCheck(strm))
         return Z_STREAM_ERROR;
     state = (struct inflate_state *)strm->state;
     if ((state->wrap & 2) == 0)
@@ -1342,7 +1355,7 @@ int ZEXPORT inflateSync(z_stream *strm) {
     struct inflate_state *state;
 
     /* check parameters */
-    if (strm == NULL || strm->state == NULL)
+    if (inflateStateCheck(strm))
         return Z_STREAM_ERROR;
     state = (struct inflate_state *)strm->state;
     if (strm->avail_in == 0 && state->bits < 8)
@@ -1392,7 +1405,7 @@ int ZEXPORT inflateSync(z_stream *strm) {
 int ZEXPORT inflateSyncPoint(z_stream *strm) {
     struct inflate_state *state;
 
-    if (strm == NULL || strm->state == NULL)
+    if (inflateStateCheck(strm))
         return Z_STREAM_ERROR;
     state = (struct inflate_state *)strm->state;
     return state->mode == STORED && state->bits == 0;
@@ -1405,8 +1418,7 @@ int ZEXPORT inflateCopy(z_stream *dest, z_stream *source) {
     unsigned wsize;
 
     /* check input */
-    if (dest == NULL || source == NULL || source->state == NULL ||
-        source->zalloc == NULL || source->zfree == NULL)
+    if (inflateStateCheck(source) || dest == NULL)
         return Z_STREAM_ERROR;
     state = (struct inflate_state *)source->state;
 
@@ -1427,6 +1439,7 @@ int ZEXPORT inflateCopy(z_stream *dest, z_stream *source) {
     /* copy state */
     memcpy((void *)dest, (void *)source, sizeof(z_stream));
     memcpy((void *)copy, (void *)state, sizeof(struct inflate_state));
+    copy->strm = dest;
     if (state->lencode >= state->codes && state->lencode <= state->codes + ENOUGH - 1) {
         copy->lencode = copy->codes + (state->lencode - state->codes);
         copy->distcode = copy->codes + (state->distcode - state->codes);
@@ -1444,7 +1457,7 @@ int ZEXPORT inflateCopy(z_stream *dest, z_stream *source) {
 int ZEXPORT inflateUndermine(z_stream *strm, int subvert) {
     struct inflate_state *state;
 
-    if (strm == NULL || strm->state == NULL)
+    if (inflateStateCheck(strm))
         return Z_STREAM_ERROR;
     state = (struct inflate_state *)strm->state;
 #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
@@ -1460,7 +1473,8 @@ int ZEXPORT inflateUndermine(z_stream *strm, int subvert) {
 int ZEXPORT inflateValidate(z_stream *strm, int check) {
     struct inflate_state *state;
 
-    if (strm == NULL || strm->state == NULL) return Z_STREAM_ERROR;
+    if (inflateStateCheck(strm))
+        return Z_STREAM_ERROR;
     state = (struct inflate_state *)strm->state;
     if (check)
         state->wrap |= 4;
@@ -1472,7 +1486,7 @@ int ZEXPORT inflateValidate(z_stream *strm, int check) {
 long ZEXPORT inflateMark(z_stream *strm) {
     struct inflate_state *state;
 
-    if (strm == NULL || strm->state == NULL)
+    if (inflateStateCheck(strm))
         return -65536;
     state = (struct inflate_state *)strm->state;
     return ((long)(state->back) << 16) + (state->mode == COPY ? state->length :
index e33330a820de2110c4ee96190ac5fa5f8f8946da..a1849e0891fc8b5bc7f0367e05821a28efaaff45 100644 (file)
--- a/inflate.h
+++ b/inflate.h
@@ -21,7 +21,7 @@
 
 /* Possible inflate modes between inflate() calls */
 typedef enum {
-    HEAD,       /* i: waiting for magic header */
+    HEAD = 16180,   /* i: waiting for magic header */
     FLAGS,      /* i: waiting for method and flags (gzip) */
     TIME,       /* i: waiting for modification time (gzip) */
     OS,         /* i: waiting for extra flags and operating system (gzip) */
@@ -83,6 +83,7 @@ typedef enum {
 /* State maintained between inflate() calls -- approximately 7K bytes, not
    including the allocated sliding window, which is up to 32K bytes. */
 struct inflate_state {
+    z_stream *strm;             /* pointer back to this zlib stream */
     inflate_mode mode;          /* current inflate mode */
     int last;                   /* true if processing last block */
     int wrap;                   /* bit 0 true for zlib, bit 1 true for gzip,