From 17d78d3b8f4aaac9dc8158a15ebf3d8951150a4d Mon Sep 17 00:00:00 2001 From: arvidn Date: Sun, 1 Oct 2017 01:24:07 +0200 Subject: [PATCH] fix bounds checking in parsing of gzip header --- src/gzip.cpp | 16 ++++++++-------- test/invalid1.gz | Bin 0 -> 27 bytes test/test_gzip.cpp | 16 ++++++++++++++++ 3 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 test/invalid1.gz diff --git a/src/gzip.cpp b/src/gzip.cpp index 3326f3c03..412cce2a1 100644 --- a/src/gzip.cpp +++ b/src/gzip.cpp @@ -112,13 +112,13 @@ namespace libtorrent { namespace { // returns -1 if gzip header is invalid or the header size in bytes - int gzip_header(span const buf) + int gzip_header(span const in) { // The zip header cannot be shorter than 10 bytes - if (buf.size() < 10) return -1; + if (in.size() < 10) return -1; span buffer( - reinterpret_cast(buf.data()), buf.size()); + reinterpret_cast(in.data()), in.size()); // gzip is defined in https://tools.ietf.org/html/rfc1952 @@ -150,22 +150,22 @@ namespace { if (flags & FNAME) { - if (buf.empty()) return -1; + if (buffer.empty()) return -1; while (buffer[0] != 0) { buffer = buffer.subspan(1); - if (buf.empty()) return -1; + if (buffer.empty()) return -1; } buffer = buffer.subspan(1); } if (flags & FCOMMENT) { - if (buf.empty()) return -1; + if (buffer.empty()) return -1; while (buffer[0] != 0) { buffer = buffer.subspan(1); - if (buf.empty()) return -1; + if (buffer.empty()) return -1; } buffer = buffer.subspan(1); } @@ -176,7 +176,7 @@ namespace { buffer = buffer.subspan(2); } - return static_cast(buf.size() - buffer.size()); + return static_cast(in.size() - buffer.size()); } } // anonymous namespace diff --git a/test/invalid1.gz b/test/invalid1.gz new file mode 100644 index 0000000000000000000000000000000000000000..731ebd1d563781fceea56f422938fbbc77aeb648 GIT binary patch literal 27 Ucmb2|<`7OT%1 zipped; + error_code ec; + load_file(combine_path("..", "invalid1.gz"), zipped, ec, 1000000); + if (ec) std::printf("failed to open file: (%d) %s\n", ec.value() + , ec.message().c_str()); + TEST_CHECK(!ec); + + std::vector inflated; + inflate_gzip(zipped, inflated, 1000000, ec); + + // we expect this to fail + TEST_CHECK(ec); +} + TORRENT_TEST(empty) { std::vector empty;