summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Stoeckmann <tobias@stoeckmann.org>2022-06-13 18:43:16 +0200
committerHans Kristian Rosbach <hk-github@circlestorm.org>2023-03-17 21:27:56 +0100
commit6e31371d8a056397e1e3b0e7ee76da4837df3093 (patch)
treea916f1913466881af01ae3b5c5dd33f02145adb0
parente9222b707c552054ea40bb7f34f2a3094da08932 (diff)
Handle invalid windowBits in init functions
Negative windowBits arguments are eventually turned positive in deflateInit2_ and inflateInit2_ (more precisely in inflateReset2). Such values are used to indicate that raw deflate/inflate should be performed. If a user supplies INT32_MIN for windowBits, the code will perform -INT32_MIN which does not fit into int32_t. In fact, this is undefined behavior in C and should be avoided. Clearly this is a user error, but given the careful validation of input arguments a few lines later in deflateInit2_ I think this might be of interest. Proof of Concept: - Compile zlib-ng with gcc -ftrapv or -fsanitize=undefined - Compile and run this program: ``` #include <limits.h> #include <stdio.h> #include <zlib-ng.h> int main(void) { zng_stream de_stream = { 0 }, in_stream = { 0 }; int result; result = zng_deflateInit2(&de_stream, 0, Z_DEFLATED, INT32_MIN, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); printf("zng_deflateInit2: %d\n", result); result = zng_inflateInit2(&in_stream, INT32_MIN); printf("zng_inflateInit2: %d\n", result); return 0; } ```
-rw-r--r--deflate.c2
-rw-r--r--inflate.c2
2 files changed, 4 insertions, 0 deletions
diff --git a/deflate.c b/deflate.c
index 4c7e179..f17fc2d 100644
--- a/deflate.c
+++ b/deflate.c
@@ -284,6 +284,8 @@ int32_t Z_EXPORT PREFIX(deflateInit2_)(PREFIX3(stream) *strm, int32_t level, int
if (windowBits < 0) { /* suppress zlib wrapper */
wrap = 0;
+ if (windowBits < -15)
+ return Z_STREAM_ERROR;
windowBits = -windowBits;
#ifdef GZIP
} else if (windowBits > 15) {
diff --git a/inflate.c b/inflate.c
index a59cd44..5a774fa 100644
--- a/inflate.c
+++ b/inflate.c
@@ -105,6 +105,8 @@ int32_t Z_EXPORT PREFIX(inflateReset2)(PREFIX3(stream) *strm, int32_t windowBits
/* extract wrap request from windowBits parameter */
if (windowBits < 0) {
wrap = 0;
+ if (windowBits < -15)
+ return Z_STREAM_ERROR;
windowBits = -windowBits;
} else {
wrap = (windowBits >> 4) + 5;