aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel
diff options
context:
space:
mode:
authorСергей Прохоров <[email protected]>2015-01-19 05:06:53 +0300
committerСергей Прохоров <[email protected]>2015-02-12 21:44:11 +0300
commitb24651c3bb6fef59c0e92c24e69151d1a92c4b08 (patch)
treeb69a6e2e6a5ffbf3c1d73d4d0170df40c1982273 /lib/kernel
parent50a92094372b45c9864afe3418b79605da549122 (diff)
downloadotp-b24651c3bb6fef59c0e92c24e69151d1a92c4b08.tar.gz
otp-b24651c3bb6fef59c0e92c24e69151d1a92c4b08.tar.bz2
otp-b24651c3bb6fef59c0e92c24e69151d1a92c4b08.zip
Add zlib limited output buffer size functionality
This functionality may be useful for compressed streams with high compression ratio (in case of gzip it may be up to x1000), when small amount of compressed data will produce large amount of uncompressed output. This may lead to DoS attacks, because server easily goes out of memory. Example of such high compression ratio stream: ``` dd if=/dev/zero of=sparse.bin bs=1MB count=100 # 100mb of zeroes gzip sparse.bin # 95kb sparse.bin.gz $ erl > {ok, Compressed} = file:read_file("sparse.bin.gz"), > 97082 = size(Compressed), > Uncompressed = zlib:gunzip(Compressed), > 100000000 = iolist_size(Uncompressed). ```
Diffstat (limited to 'lib/kernel')
-rw-r--r--lib/kernel/test/zlib_SUITE.erl35
1 files changed, 34 insertions, 1 deletions
diff --git a/lib/kernel/test/zlib_SUITE.erl b/lib/kernel/test/zlib_SUITE.erl
index 3be6f39d95..e99151284f 100644
--- a/lib/kernel/test/zlib_SUITE.erl
+++ b/lib/kernel/test/zlib_SUITE.erl
@@ -82,7 +82,7 @@ groups() ->
api_deflateSetDictionary, api_deflateReset,
api_deflateParams, api_deflate, api_deflateEnd,
api_inflateInit, api_inflateSetDictionary,
- api_inflateSync, api_inflateReset, api_inflate,
+ api_inflateSync, api_inflateReset, api_inflate, api_inflateChunk,
api_inflateEnd, api_setBufsz, api_getBufsz, api_crc32,
api_adler32, api_getQSize, api_un_compress, api_un_zip,
api_g_un_zip]},
@@ -357,6 +357,39 @@ api_inflate(Config) when is_list(Config) ->
?m({'EXIT',{data_error,_}}, zlib:inflate(Z1, <<2,1,2,1,2>>)),
?m(ok, zlib:close(Z1)).
+api_inflateChunk(doc) -> "Test inflateChunk";
+api_inflateChunk(suite) -> [];
+api_inflateChunk(Config) when is_list(Config) ->
+ ChunkSize = 1024,
+ Data = << <<(I rem 150)>> || I <- lists:seq(1, 3 * ChunkSize) >>,
+ Part1 = binary:part(Data, 0, ChunkSize),
+ Part2 = binary:part(Data, ChunkSize, ChunkSize),
+ Part3 = binary:part(Data, ChunkSize * 2, ChunkSize),
+ ?line Compressed = zlib:compress(Data),
+ ?line Z1 = zlib:open(),
+ ?line zlib:setBufSize(Z1, ChunkSize),
+ ?m(ok, zlib:inflateInit(Z1)),
+ ?m([], zlib:inflateChunk(Z1, <<>>)),
+ ?m({more, Part1}, zlib:inflateChunk(Z1, Compressed)),
+ ?m({more, Part2}, zlib:inflateChunk(Z1)),
+ ?m(Part3, zlib:inflateChunk(Z1)),
+ ?m(ok, zlib:inflateEnd(Z1)),
+
+ ?m(ok, zlib:inflateInit(Z1)),
+ ?m({more, Part1}, zlib:inflateChunk(Z1, Compressed)),
+
+ ?m(ok, zlib:inflateReset(Z1)),
+
+ ?line zlib:setBufSize(Z1, size(Data)),
+ ?m(Data, zlib:inflateChunk(Z1, Compressed)),
+ ?m(ok, zlib:inflateEnd(Z1)),
+
+ ?m(ok, zlib:inflateInit(Z1)),
+ ?m(?BARG, zlib:inflateChunk(gurka, Compressed)),
+ ?m(?BARG, zlib:inflateChunk(Z1, 4384)),
+ ?m({'EXIT',{data_error,_}}, zlib:inflateEnd(Z1)),
+ ?m(ok, zlib:close(Z1)).
+
api_inflateEnd(doc) -> "Test inflateEnd";
api_inflateEnd(suite) -> [];
api_inflateEnd(Config) when is_list(Config) ->