From b1cc968969907951dcc114a4622a4969476bb8b9 Mon Sep 17 00:00:00 2001 From: Guido Vranken Date: Wed, 10 Aug 2022 00:04:56 +0200 Subject: [PATCH] Fix out-of-bounds read in torrent parsing (#3600) Fixes #3591 --- libtransmission/torrent-metainfo.cc | 16 ++++++++++++---- tests/libtransmission/torrent-metainfo-test.cc | 7 +++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/libtransmission/torrent-metainfo.cc b/libtransmission/torrent-metainfo.cc index cec210d27..f500c9b5d 100644 --- a/libtransmission/torrent-metainfo.cc +++ b/libtransmission/torrent-metainfo.cc @@ -455,10 +455,18 @@ struct MetainfoHandler final : public transmission::benc::BasicHandler(std::data(tm_.pieces_))); - tm_.pieces_offset_ = context.tokenSpan().first; + if (std::size(value) % sizeof(tr_sha1_digest_t) == 0) + { + auto const n = std::size(value) / sizeof(tr_sha1_digest_t); + tm_.pieces_.resize(n); + std::copy_n(std::data(value), std::size(value), reinterpret_cast(std::data(tm_.pieces_))); + tm_.pieces_offset_ = context.tokenSpan().first; + } + else + { + tr_error_set(context.error, EINVAL, fmt::format("invalid piece size: {}", std::size(value))); + unhandled = true; + } } else if (pathStartsWith(PieceLayersKey)) { diff --git a/tests/libtransmission/torrent-metainfo-test.cc b/tests/libtransmission/torrent-metainfo-test.cc index 0d3c4c6eb..31c93dbe9 100644 --- a/tests/libtransmission/torrent-metainfo-test.cc +++ b/tests/libtransmission/torrent-metainfo-test.cc @@ -255,5 +255,12 @@ TEST_F(TorrentMetainfoTest, GetRightStyleWebseedString) EXPECT_EQ("http://www.webseed-one.com/"sv, tm.webseed(0)); } +// Test for https://github.com/transmission/transmission/issues/3591 +TEST_F(TorrentMetainfoTest, parseBencOOBWrite) +{ + auto tm = tr_torrent_metainfo{}; + EXPECT_FALSE(tm.parseBenc(tr_base64_decode("ZGg0OmluZm9kNjpwaWVjZXMzOkFpzQ=="))); +} + } // namespace test } // namespace libtransmission