Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Tor
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Container Registry
Model registry
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
The Tor Project
Core
Tor
Commits
81cfd5c9
Commit
81cfd5c9
authored
8 years ago
by
Nick Mathewson
Browse files
Options
Downloads
Plain Diff
Merge branch 'zlib_coverage_squashed'
parents
b421648d
d937b866
Branches
bug16937-02
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
changes/test_zlib_bombs
+3
-0
3 additions, 0 deletions
changes/test_zlib_bombs
changes/zlib_12
+4
-0
4 additions, 0 deletions
changes/zlib_12
src/common/torgzip.c
+13
-46
13 additions, 46 deletions
src/common/torgzip.c
src/test/test_util.c
+63
-16
63 additions, 16 deletions
src/test/test_util.c
with
83 additions
and
62 deletions
changes/test_zlib_bombs
0 → 100644
+
3
−
0
View file @
81cfd5c9
o Testing:
- We now have unit tests for our code to reject zlib "compression bombs".
(Fortunately, the code works fine.)
This diff is collapsed.
Click to expand it.
changes/zlib_12
0 → 100644
+
4
−
0
View file @
81cfd5c9
o New system requirements:
- We now require zlib version 1.2 or later. (Back when we started,
zlib 1.1 and zlib 1.0 were still found in the wild. 1.2 was released in
2003. We recommend the latest version.)
This diff is collapsed.
Click to expand it.
src/common/torgzip.c
+
13
−
46
View file @
81cfd5c9
...
...
@@ -46,34 +46,16 @@
#include
<zlib.h>
#if defined ZLIB_VERNUM && ZLIB_VERNUM < 0x1200
#error "We require zlib version 1.2 or later."
#endif
static
size_t
tor_zlib_state_size_precalc
(
int
inflate
,
int
windowbits
,
int
memlevel
);
/** Total number of bytes allocated for zlib state */
static
size_t
total_zlib_allocation
=
0
;
/** Set to 1 if zlib is a version that supports gzip; set to 0 if it doesn't;
* set to -1 if we haven't checked yet. */
static
int
gzip_is_supported
=
-
1
;
/** Return true iff we support gzip-based compression. Otherwise, we need to
* use zlib. */
int
is_gzip_supported
(
void
)
{
if
(
gzip_is_supported
>=
0
)
return
gzip_is_supported
;
if
(
!
strcmpstart
(
ZLIB_VERSION
,
"0."
)
||
!
strcmpstart
(
ZLIB_VERSION
,
"1.0"
)
||
!
strcmpstart
(
ZLIB_VERSION
,
"1.1"
))
gzip_is_supported
=
0
;
else
gzip_is_supported
=
1
;
return
gzip_is_supported
;
}
/** Return a string representation of the version of the currently running
* version of zlib. */
const
char
*
...
...
@@ -165,12 +147,6 @@ tor_gzip_compress(char **out, size_t *out_len,
*
out
=
NULL
;
if
(
method
==
GZIP_METHOD
&&
!
is_gzip_supported
())
{
/* Old zlib version don't support gzip in deflateInit2 */
log_warn
(
LD_BUG
,
"Gzip not supported with zlib %s"
,
ZLIB_VERSION
);
goto
err
;
}
stream
=
tor_malloc_zero
(
sizeof
(
struct
z_stream_s
));
stream
->
zalloc
=
Z_NULL
;
stream
->
zfree
=
Z_NULL
;
...
...
@@ -182,9 +158,11 @@ tor_gzip_compress(char **out, size_t *out_len,
method_bits
(
method
,
HIGH_COMPRESSION
),
get_memlevel
(
HIGH_COMPRESSION
),
Z_DEFAULT_STRATEGY
)
!=
Z_OK
)
{
//LCOV_EXCL_START -- we can only provoke failure by giving junk arguments.
log_warn
(
LD_GENERAL
,
"Error from deflateInit2: %s"
,
stream
->
msg
?
stream
->
msg
:
"<no message>"
);
goto
err
;
//LCOV_EXCL_STOP
}
/* Guess 50% compression. */
...
...
@@ -237,13 +215,12 @@ tor_gzip_compress(char **out, size_t *out_len,
* the newly unsigned field isn't negative." */
tor_assert
(
stream
->
total_out
>=
0
);
#endif
if
(((
size_t
)
stream
->
total_out
)
>
out_size
+
4097
)
{
/* If we're wasting more than 4k, don't. */
*
out
=
tor_realloc
(
*
out
,
stream
->
total_out
+
1
);
}
if
(
deflateEnd
(
stream
)
!=
Z_OK
)
{
// LCOV_EXCL_START -- unreachable if we handled the zlib structure right
tor_assert_nonfatal_unreached
();
log_warn
(
LD_BUG
,
"Error freeing gzip structures"
);
goto
err
;
// LCOV_EXCL_STOP
}
tor_free
(
stream
);
...
...
@@ -291,12 +268,6 @@ tor_gzip_uncompress(char **out, size_t *out_len,
tor_assert
(
in
);
tor_assert
(
in_len
<
UINT_MAX
);
if
(
method
==
GZIP_METHOD
&&
!
is_gzip_supported
())
{
/* Old zlib version don't support gzip in inflateInit2 */
log_warn
(
LD_BUG
,
"Gzip not supported with zlib %s"
,
ZLIB_VERSION
);
return
-
1
;
}
*
out
=
NULL
;
stream
=
tor_malloc_zero
(
sizeof
(
struct
z_stream_s
));
...
...
@@ -308,9 +279,11 @@ tor_gzip_uncompress(char **out, size_t *out_len,
if
(
inflateInit2
(
stream
,
method_bits
(
method
,
HIGH_COMPRESSION
))
!=
Z_OK
)
{
// LCOV_EXCL_START -- can only hit this if we give bad inputs.
log_warn
(
LD_GENERAL
,
"Error from inflateInit2: %s"
,
stream
->
msg
?
stream
->
msg
:
"<no message>"
);
goto
err
;
// LCOV_EXCL_STOP
}
out_size
=
in_len
*
2
;
/* guess 50% compression. */
...
...
@@ -451,12 +424,6 @@ tor_zlib_new(int compress, compress_method_t method,
tor_zlib_state_t
*
out
;
int
bits
,
memlevel
;
if
(
method
==
GZIP_METHOD
&&
!
is_gzip_supported
())
{
/* Old zlib version don't support gzip in inflateInit2 */
log_warn
(
LD_BUG
,
"Gzip not supported with zlib %s"
,
ZLIB_VERSION
);
return
NULL
;
}
if
(
!
compress
)
{
/* use this setting for decompression, since we might have the
* max number of window bits */
...
...
@@ -474,10 +441,10 @@ tor_zlib_new(int compress, compress_method_t method,
if
(
deflateInit2
(
&
out
->
stream
,
Z_BEST_COMPRESSION
,
Z_DEFLATED
,
bits
,
memlevel
,
Z_DEFAULT_STRATEGY
)
!=
Z_OK
)
goto
err
;
goto
err
;
// LCOV_EXCL_LINE
}
else
{
if
(
inflateInit2
(
&
out
->
stream
,
bits
)
!=
Z_OK
)
goto
err
;
goto
err
;
// LCOV_EXCL_LINE
}
out
->
allocation
=
tor_zlib_state_size_precalc
(
!
compress
,
bits
,
memlevel
);
...
...
This diff is collapsed.
Click to expand it.
src/test/test_util.c
+
63
−
16
View file @
81cfd5c9
...
...
@@ -1821,22 +1821,21 @@ test_util_gzip(void *arg)
(
void
)
arg
;
buf1
=
tor_strdup
(
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ"
);
tt_assert
(
detect_compression_method
(
buf1
,
strlen
(
buf1
))
==
UNKNOWN_METHOD
);
if
(
is_gzip_supported
())
{
tt_assert
(
!
tor_gzip_compress
(
&
buf2
,
&
len1
,
buf1
,
strlen
(
buf1
)
+
1
,
GZIP_METHOD
));
tt_assert
(
buf2
);
tt_assert
(
len1
<
strlen
(
buf1
));
tt_assert
(
detect_compression_method
(
buf2
,
len1
)
==
GZIP_METHOD
);
tt_assert
(
!
tor_gzip_uncompress
(
&
buf3
,
&
len2
,
buf2
,
len1
,
GZIP_METHOD
,
1
,
LOG_INFO
));
tt_assert
(
buf3
);
tt_int_op
(
strlen
(
buf1
)
+
1
,
OP_EQ
,
len2
);
tt_str_op
(
buf1
,
OP_EQ
,
buf3
);
tor_free
(
buf2
);
tor_free
(
buf3
);
}
tt_assert
(
!
tor_gzip_compress
(
&
buf2
,
&
len1
,
buf1
,
strlen
(
buf1
)
+
1
,
GZIP_METHOD
));
tt_assert
(
buf2
);
tt_assert
(
len1
<
strlen
(
buf1
));
tt_assert
(
detect_compression_method
(
buf2
,
len1
)
==
GZIP_METHOD
);
tt_assert
(
!
tor_gzip_uncompress
(
&
buf3
,
&
len2
,
buf2
,
len1
,
GZIP_METHOD
,
1
,
LOG_INFO
));
tt_assert
(
buf3
);
tt_int_op
(
strlen
(
buf1
)
+
1
,
OP_EQ
,
len2
);
tt_str_op
(
buf1
,
OP_EQ
,
buf3
);
tor_free
(
buf2
);
tor_free
(
buf3
);
tt_assert
(
!
tor_gzip_compress
(
&
buf2
,
&
len1
,
buf1
,
strlen
(
buf1
)
+
1
,
ZLIB_METHOD
));
...
...
@@ -1920,6 +1919,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
)
...
...
@@ -4935,6 +4981,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
),
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment