Fix out-of-bounds read in torrent parsing (#3600)

Fixes #3591
This commit is contained in:
Guido Vranken 2022-08-10 00:04:56 +02:00 committed by GitHub
parent a5f7df34ab
commit b1cc968969
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 4 deletions

View File

@ -455,10 +455,18 @@ struct MetainfoHandler final : public transmission::benc::BasicHandler<MaxBencDe
}
else if (pathIs(InfoKey, PiecesKey))
{
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<char*>(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<char*>(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))
{

View File

@ -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