From f14f7db76801218600a0a2e039011414ff8c0a96 Mon Sep 17 00:00:00 2001 From: "Michael Altizer (mialtize)" Date: Tue, 10 Jan 2017 11:43:20 -0500 Subject: [PATCH] Merge pull request #770 in SNORT/snort3 from modern_zlib to master Squashed commit of the following: commit 152f75000bddbafd0180352d4208cb4eae1c3d70 Author: Michael Altizer Date: Mon Jan 9 21:38:56 2017 -0500 http_server: Do not copy zlib z_stream object after initialization More recent versions of zlib now include a backreference from the stream state to the stream object for sanity checking, which becomes invalid if the z_stream object is copied by value. Future functions called using the copied object will fail due to the sanity checks. http_server was doing this for no obvious reason, so this patch fixes it. commit 25eef766344d6c24f096f3f0ecc175b244a8ef41 Author: Michael Altizer Date: Mon Jan 9 21:31:29 2017 -0500 so_manager: Use the lowest legal value for windowBits in deflateInit2() The current value of -8 is not legal due to a bug in deflate with windowBits == 8 (256-byte window). Newer versions of zlib are actively enforcing this restriction when headers are being excluded as Snort does and cause deflateInit2() to fail. It used to silently change the windowBits to 9, so now do so explicitly. See also: https://github.com/madler/zlib/commit/049578f0a1849f502834167e233f4c1d52ddcbcc as well as the zlib manual (http://www.zlib.net/manual.html) --- extra/src/inspectors/http_server/hi_server.cc | 63 ++++++++----------- src/managers/so_manager.cc | 2 +- 2 files changed, 27 insertions(+), 38 deletions(-) diff --git a/extra/src/inspectors/http_server/hi_server.cc b/extra/src/inspectors/http_server/hi_server.cc index 6c616b099..0c88f3729 100644 --- a/extra/src/inspectors/http_server/hi_server.cc +++ b/extra/src/inspectors/http_server/hi_server.cc @@ -898,50 +898,41 @@ static void SetGzipBuffers(HttpSessionData* hsd, HI_SESSION* session) static int uncompress_gzip(u_char* dest, int destLen, const u_char* source, int sourceLen, HttpSessionData* sd, int* total_bytes_read, int compr_fmt) { - z_stream stream; + z_stream* stream; int err; int iRet = HI_SUCCESS; - stream = sd->decomp_state->d_stream; + stream = &sd->decomp_state->d_stream; - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; - if ((uLong)stream.avail_in != (uLong)sourceLen) - { - sd->decomp_state->d_stream = stream; + stream->next_in = (Bytef*)source; + stream->avail_in = (uInt)sourceLen; + if ((uLong)stream->avail_in != (uLong)sourceLen) return HI_FATAL_ERR; - } - stream.next_out = dest; - stream.avail_out = (uInt)destLen; - if ((uLong)stream.avail_out != (uLong)destLen) - { - sd->decomp_state->d_stream = stream; + stream->next_out = dest; + stream->avail_out = (uInt)destLen; + if ((uLong)stream->avail_out != (uLong)destLen) return HI_FATAL_ERR; - } if (!sd->decomp_state->inflate_init) { sd->decomp_state->inflate_init = 1; - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; + stream->zalloc = (alloc_func)0; + stream->zfree = (free_func)0; if (compr_fmt & HTTP_RESP_COMPRESS_TYPE__DEFLATE) - err = inflateInit(&stream); + err = inflateInit(stream); else - err = inflateInit2(&stream, GZIP_WBITS); + err = inflateInit2(stream, GZIP_WBITS); if (err != Z_OK) - { - sd->decomp_state->d_stream = stream; return HI_FATAL_ERR; - } } else { - stream.total_in = 0; - stream.total_out =0; + stream->total_in = 0; + stream->total_out =0; } - err = inflate(&stream, Z_SYNC_FLUSH); + err = inflate(stream, Z_SYNC_FLUSH); if ((!sd->decomp_state->deflate_initialized) && (err == Z_DATA_ERROR) && (compr_fmt & HTTP_RESP_COMPRESS_TYPE__DEFLATE)) @@ -949,38 +940,36 @@ static int uncompress_gzip(u_char* dest, int destLen, const u_char* source, /* Might not have zlib header - add one */ static constexpr char zlib_header[2] = { 0x78, 0x01 }; - inflateReset(&stream); - stream.next_in = (Bytef*)zlib_header; - stream.avail_in = sizeof(zlib_header); + inflateReset(stream); + stream->next_in = (Bytef*)zlib_header; + stream->avail_in = sizeof(zlib_header); sd->decomp_state->deflate_initialized = true; - err = inflate(&stream, Z_SYNC_FLUSH); + err = inflate(stream, Z_SYNC_FLUSH); if (err == Z_OK) { - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; + stream->next_in = (Bytef*)source; + stream->avail_in = (uInt)sourceLen; - err = inflate(&stream, Z_SYNC_FLUSH); + err = inflate(stream, Z_SYNC_FLUSH); } } if ((err != Z_STREAM_END) && (err !=Z_OK)) { /* If some of the compressed data is decompressed we need to provide that for detection */ - if (( stream.total_out > 0) && (err != Z_DATA_ERROR)) + if (( stream->total_out > 0) && (err != Z_DATA_ERROR)) { - *total_bytes_read = stream.total_out; + *total_bytes_read = stream->total_out; iRet = HI_NONFATAL_ERR; } else iRet = HI_FATAL_ERR; - inflateEnd(&stream); - sd->decomp_state->d_stream = stream; + inflateEnd(stream); return iRet; } - *total_bytes_read = stream.total_out; - sd->decomp_state->d_stream = stream; + *total_bytes_read = stream->total_out; return HI_SUCCESS; } diff --git a/src/managers/so_manager.cc b/src/managers/so_manager.cc index f98e2a3f9..70208e90f 100644 --- a/src/managers/so_manager.cc +++ b/src/managers/so_manager.cc @@ -66,7 +66,7 @@ void SoManager::dump_plugins() //------------------------------------------------------------------------- // FIXIT-L eliminate this arbitrary limit on rule text size -const unsigned window_bits = -8; +const unsigned window_bits = -9; const unsigned max_rule = 128000; static uint8_t so_buf[max_rule]; -- 2.47.2