diff options
author | Sebastian Pop <s.pop@samsung.com> | 2018-09-24 09:57:48 -0500 |
---|---|---|
committer | Hans Kristian Rosbach <hk-github@circlestorm.org> | 2018-10-16 13:53:02 +0200 |
commit | 2071b9349e3df5431f81613a43f3a4369a9ae3e5 (patch) | |
tree | 370460e49e7b07d00a53fae8a441cecbc9975fba /deflate_slow.c | |
parent | 3f4de7e7b4878f2aed96ea24f96c61b628962f9b (diff) |
fix bug #207: avoid undefined integer overflow
zlib-ng used to fail when compiled with UBSan with this error:
deflate_slow.c:112:21: runtime error: unsigned integer overflow: 45871 - 45872 cannot be represented in type 'unsigned int'
The bug occurs in code added to zlib-ng under `#ifndef NOT_TWEAK_COMPILER`.
The original code of zlib contains a loop with two induction variables:
s->prev_length -= 2;
do {
if (++s->strstart <= max_insert) {
functable.insert_string(s, s->strstart, 1);
}
} while (--s->prev_length != 0);
The function insert_string is not executed when
!(++s->strstart <= max_insert)
i.e., when
!(s->strstart + 1 <= max_insert)
!(s->strstart < max_insert)
max_insert <= s->strstart
The function insert_string is executed when
++s->strstart <= max_insert
i.e., when
s->strstart + 1 <= max_insert
s->strstart < max_insert
The function is executed at most `max_insert - s->strstart` times, following the
exit condition of the do-while `(--s->prev_length != 0)`. If the loop exits
after evaluating the exit condition once, the function is executed once
independently of `max_insert - s->strstart`. The number of times the function
executes is the minimum between the number of iterations in the do-while loop
and `max_insert - s->strstart`.
The number of iterations of the loop is `mov_fwd = s->prev_length - 2`, and we
know that this is at least one as otherwise `--s->prev_length` would overflow.
The number of times the function insert_string is called is
`min(mov_fwd, max_insert - s->strstart)`
Diffstat (limited to 'deflate_slow.c')
-rw-r--r-- | deflate_slow.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/deflate_slow.c b/deflate_slow.c index 1763477..de53b2d 100644 --- a/deflate_slow.c +++ b/deflate_slow.c @@ -108,11 +108,13 @@ ZLIB_INTERNAL block_state deflate_slow(deflate_state *s, int flush) { #else { unsigned int mov_fwd = s->prev_length - 2; - unsigned int insert_cnt = mov_fwd; - if (unlikely(insert_cnt > max_insert - s->strstart)) - insert_cnt = max_insert - s->strstart; + if (max_insert > s->strstart) { + unsigned int insert_cnt = mov_fwd; + if (unlikely(insert_cnt > max_insert - s->strstart)) + insert_cnt = max_insert - s->strstart; - functable.insert_string(s, s->strstart + 1, insert_cnt); + functable.insert_string(s, s->strstart + 1, insert_cnt); + } s->prev_length = 0; s->match_available = 0; s->match_length = MIN_MATCH-1; |