diff --git a/fec/fec.cpp b/fec/fec.cpp index b194a173..102df038 100644 --- a/fec/fec.cpp +++ b/fec/fec.cpp @@ -19,6 +19,7 @@ #include "fec.h" #include "td/utils/overloaded.h" #include "auto/tl/ton_api.hpp" +#include "td/utils/misc.h" namespace ton { @@ -98,24 +99,37 @@ td::uint32 FecType::symbol_size() const { } td::Result FecType::create(tl_object_ptr obj) { + td::int32 data_size_int, symbol_size_int, symbols_count_int; + ton_api::downcast_call(*obj, td::overloaded([&](const auto &obj) { + data_size_int = obj.data_size_; + symbol_size_int = obj.symbol_size_; + symbols_count_int = obj.symbols_count_; + })); + TRY_RESULT(data_size, td::narrow_cast_safe(data_size_int)); + TRY_RESULT(symbol_size, td::narrow_cast_safe(symbol_size_int)); + TRY_RESULT(symbols_count, td::narrow_cast_safe(symbols_count_int)); + + if (symbol_size == 0) { + return td::Status::Error("invalid fec type: symbol_size is 0"); + } + if (symbol_size > 1 << 11) { + return td::Status::Error("invalid fec type: symbol_size is too big"); + } + if (symbols_count != (data_size + symbol_size - 1) / symbol_size) { + return td::Status::Error("invalid fec type: wrong symbols_count"); + } FecType T; - ton_api::downcast_call( - *obj.get(), td::overloaded( - [&](const ton_api::fec_raptorQ &obj) { - T.type_ = td::fec::RaptorQEncoder::Parameters{static_cast(obj.data_size_), - static_cast(obj.symbol_size_), - static_cast(obj.symbols_count_)}; - }, - [&](const ton_api::fec_roundRobin &obj) { - T.type_ = td::fec::RoundRobinEncoder::Parameters{static_cast(obj.data_size_), - static_cast(obj.symbol_size_), - static_cast(obj.symbols_count_)}; - }, - [&](const ton_api::fec_online &obj) { - T.type_ = td::fec::OnlineEncoder::Parameters{static_cast(obj.data_size_), - static_cast(obj.symbol_size_), - static_cast(obj.symbols_count_)}; - })); + ton_api::downcast_call(*obj, + td::overloaded( + [&](const ton_api::fec_raptorQ &obj) { + T.type_ = td::fec::RaptorQEncoder::Parameters{data_size, symbol_size, symbols_count}; + }, + [&](const ton_api::fec_roundRobin &obj) { + T.type_ = td::fec::RoundRobinEncoder::Parameters{data_size, symbol_size, symbols_count}; + }, + [&](const ton_api::fec_online &obj) { + T.type_ = td::fec::OnlineEncoder::Parameters{data_size, symbol_size, symbols_count}; + })); return T; } diff --git a/overlay/overlay-fec-broadcast.cpp b/overlay/overlay-fec-broadcast.cpp index 7ff08309..aed5248b 100644 --- a/overlay/overlay-fec-broadcast.cpp +++ b/overlay/overlay-fec-broadcast.cpp @@ -28,8 +28,8 @@ td::Result> BroadcastFec::create(Overlay::Broadcas Overlay::BroadcastDataHash data_hash, td::uint32 flags, td::uint32 date, fec::FecType fec_type) { auto F = std::make_unique(hash, std::move(src), data_hash, flags, date, std::move(fec_type)); - TRY_STATUS(F->init_fec_type()); TRY_STATUS(F->run_checks()); + TRY_STATUS(F->init_fec_type()); return std::move(F); } diff --git a/rldp/rldp-peer.cpp b/rldp/rldp-peer.cpp index 6192d070..c599e949 100644 --- a/rldp/rldp-peer.cpp +++ b/rldp/rldp-peer.cpp @@ -125,6 +125,10 @@ void RldpTransferReceiverImpl::receive_part(fec::FecType fec_type, td::uint32 pa } if (!decoder_) { + if (offset_ + fec_type.size() > total_size_) { + VLOG(RLDP_NOTICE) << "failed to create decoder: data size in fec type is too big"; + return; + } auto D = fec_type.create_decoder(); if (D.is_error()) { VLOG(RLDP_WARNING) << "failed to create decoder: " << D.move_as_error();