diff options
author | Nick Mathewson <nickm@torproject.org> | 2016-06-08 18:08:30 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2016-06-08 18:08:30 -0400 |
commit | f016213f7fde4a0aac359a324baf42ad2356e169 (patch) | |
tree | d5f7fe8a0c4e91ad215e059d8ff1ae9052065f0c /src/test/test_util.c | |
parent | 1e330e1947b750be12b217c944534f9284509751 (diff) | |
download | tor-f016213f7fde4a0aac359a324baf42ad2356e169.tar.gz tor-f016213f7fde4a0aac359a324baf42ad2356e169.zip |
Unit tests for our zlib code to test and reject compression bombs.
Diffstat (limited to 'src/test/test_util.c')
-rw-r--r-- | src/test/test_util.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/test/test_util.c b/src/test/test_util.c index c3c6035ba4..8b9d5ea475 100644 --- a/src/test/test_util.c +++ b/src/test/test_util.c @@ -1836,6 +1836,53 @@ test_util_gzip(void *arg) tor_free(buf1); } +static void +test_util_gzip_compression_bomb(void *arg) +{ + /* A 'compression bomb' is a very small object that uncompresses to a huge + * one. Most compression formats support them, but they can be a DOS vector. + * In Tor we try not to generate them, and we don't accept them. + */ + (void) arg; + size_t one_million = 1<<20; + char *one_mb = tor_malloc_zero(one_million); + char *result = NULL; + size_t result_len = 0; + tor_zlib_state_t *state = NULL; + + /* Make sure we can't produce a compression bomb */ + tt_int_op(-1, OP_EQ, tor_gzip_compress(&result, &result_len, + one_mb, one_million, + ZLIB_METHOD)); + + /* Here's a compression bomb that we made manually. */ + const char compression_bomb[1039] = + { 0x78, 0xDA, 0xED, 0xC1, 0x31, 0x01, 0x00, 0x00, 0x00, 0xC2, + 0xA0, 0xF5, 0x4F, 0x6D, 0x08, 0x5F, 0xA0 /* .... */ }; + tt_int_op(-1, OP_EQ, tor_gzip_uncompress(&result, &result_len, + compression_bomb, 1039, + ZLIB_METHOD, 0, LOG_WARN)); + + + /* Now try streaming that. */ + state = tor_zlib_new(0, ZLIB_METHOD, HIGH_COMPRESSION); + tor_zlib_output_t r; + const char *inp = compression_bomb; + size_t inlen = 1039; + do { + char *outp = one_mb; + size_t outleft = 4096; /* small on purpose */ + r = tor_zlib_process(state, &outp, &outleft, &inp, &inlen, 0); + tt_int_op(inlen, OP_NE, 0); + } while (r == TOR_ZLIB_BUF_FULL); + + tt_int_op(r, OP_EQ, TOR_ZLIB_ERR); + + done: + tor_free(one_mb); + tor_zlib_free(state); +} + /** Run unit tests for mmap() wrapper functionality. */ static void test_util_mmap(void *arg) @@ -4800,6 +4847,7 @@ struct testcase_t util_tests[] = { UTIL_LEGACY(strmisc), UTIL_LEGACY(pow2), UTIL_LEGACY(gzip), + UTIL_LEGACY(gzip_compression_bomb), UTIL_LEGACY(datadir), UTIL_LEGACY(memarea), UTIL_LEGACY(control_formats), |