diff --git a/CHANGELOG.md b/CHANGELOG.md index e724bf71..d7fd7d75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ Version XXX: +* Fix CVE-2016-9840 in zlib implementation. * Fix TLS SNI handling in websocket_client_async_ssl example. * Fix reuse of sliding window in WebSocket permessage_deflate. * Fix accept error handling in http_server_async example. diff --git a/include/boost/beast/zlib/detail/inflate_stream.ipp b/include/boost/beast/zlib/detail/inflate_stream.ipp index 37955b9c..42e033ae 100644 --- a/include/boost/beast/zlib/detail/inflate_stream.ipp +++ b/include/boost/beast/zlib/detail/inflate_stream.ipp @@ -572,7 +572,7 @@ inflate_table( code *next; // next available space in table std::uint16_t const* base; // base value table to use std::uint16_t const* extra; // extra bits table to use - int end; // use base and extra for symbol > end + unsigned match; // use base and extra for symbol >= match std::uint16_t count[15+1]; // number of codes of each length std::uint16_t offs[15+1]; // offsets in table for each length @@ -584,7 +584,7 @@ inflate_table( // Length codes 257..285 extra static std::uint16_t constexpr lext[31] = { 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202}; // Distance codes 0..29 base static std::uint16_t constexpr dbase[32] = { @@ -722,19 +722,17 @@ inflate_table( { case build::codes: base = extra = work; /* dummy value--not used */ - end = 19; + match = 20; break; case build::lens: base = lbase; - base -= 257; extra = lext; - extra -= 257; - end = 256; + match = 257; break; default: /* build::dists */ base = dbase; extra = dext; - end = -1; + match = 0; } /* initialize state for loop */ @@ -764,15 +762,15 @@ inflate_table( { /* create table entry */ here.bits = (std::uint8_t)(len - drop); - if ((int)(work[sym]) < end) + if (work[sym] + 1U < match) { here.op = (std::uint8_t)0; here.val = work[sym]; } - else if ((int)(work[sym]) > end) + else if (work[sym] >= match) { - here.op = (std::uint8_t)(extra[work[sym]]); - here.val = base[work[sym]]; + here.op = (std::uint8_t)(extra[work[sym] - match]); + here.val = base[work[sym] - match]; } else {