From 86c37af147588db551921689fc696ca67835f1e6 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Fri, 29 Sep 2017 08:30:52 -0700 Subject: [PATCH] fix integer overflow in torrent_info --- src/assert.cpp | 2 +- src/block_cache.cpp | 2 +- src/torrent_info.cpp | 15 ++++++++++++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/assert.cpp b/src/assert.cpp index 3c4d355ec..e5fb40e58 100644 --- a/src/assert.cpp +++ b/src/assert.cpp @@ -358,7 +358,7 @@ TORRENT_EXPORT void assert_fail(char const* expr, int line #else // send SIGINT to the current process // to break into the debugger - ::raise(SIGINT); + ::raise(SIGABRT); #endif ::abort(); #endif diff --git a/src/block_cache.cpp b/src/block_cache.cpp index 7314514ec..124947cf5 100644 --- a/src/block_cache.cpp +++ b/src/block_cache.cpp @@ -295,7 +295,7 @@ static_assert(int(job_action_name.size()) == static_cast(job_action_t::num_ #define TORRENT_PIECE_ASSERT(cond, piece) \ - do { if (!(cond)) { assert_print_piece(piece); assert_fail(#cond, __LINE__, __FILE__, TORRENT_FUNCTION, 0); } } TORRENT_WHILE_0 + do { if (!(cond)) { assert_print_piece(piece); assert_fail(#cond, __LINE__, __FILE__, TORRENT_FUNCTION, nullptr); } } TORRENT_WHILE_0 #else #define TORRENT_PIECE_ASSERT(cond, piece) do {} TORRENT_WHILE_0 diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index 9e2cd2a66..4ff9ae15f 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -944,14 +944,14 @@ namespace { ptrdiff_t const info_ptr_diff = m_info_section.get() - section.data(); // extract piece length - int piece_length = int(info.dict_find_int_value("piece length", -1)); - if (piece_length <= 0) + std::int64_t piece_length = info.dict_find_int_value("piece length", -1); + if (piece_length <= 0 || piece_length > std::numeric_limits::max()) { ec = errors::torrent_missing_piece_length; return false; } file_storage files; - files.set_piece_length(piece_length); + files.set_piece_length(static_cast(piece_length)); // extract file name (or the directory name if it's a multi file libtorrent) bdecode_node name_ent = info.dict_find_string("name.utf-8"); @@ -1001,6 +1001,15 @@ namespace { // we want this division to round upwards, that's why we have the // extra addition + if (files.total_size() >= std::numeric_limits::max() + - files.piece_length()) + { + ec = errors::too_many_pieces_in_torrent; + // mark the torrent as invalid + m_files.set_piece_length(0); + return false; + } + files.set_num_pieces(int((files.total_size() + files.piece_length() - 1) / files.piece_length()));