diff options
author | Tobias Stoeckmann <tobias@stoeckmann.org> | 2022-06-13 18:43:16 +0200 |
---|---|---|
committer | Hans Kristian Rosbach <hk-github@circlestorm.org> | 2023-03-17 21:27:56 +0100 |
commit | 6e31371d8a056397e1e3b0e7ee76da4837df3093 (patch) | |
tree | a916f1913466881af01ae3b5c5dd33f02145adb0 | |
parent | e9222b707c552054ea40bb7f34f2a3094da08932 (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.c | 2 | ||||
-rw-r--r-- | inflate.c | 2 |
2 files changed, 4 insertions, 0 deletions
@@ -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) { @@ -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; |