Skip to content

Commit

Permalink
add empty container sanity checks when using front() and back()
Browse files Browse the repository at this point in the history
  • Loading branch information
moneromooo-monero committed Dec 18, 2017
1 parent 56fa6ce commit 45a1c4c
Show file tree
Hide file tree
Showing 9 changed files with 32 additions and 6 deletions.
2 changes: 1 addition & 1 deletion contrib/epee/include/net/abstract_tcp_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ namespace net_utils
m_connections.back().powner = this;
m_connections.back().m_self_it = --m_connections.end();
m_connections.back().m_context.m_remote_address = remote_address;
m_connections.back().m_htread = threads_helper::create_thread(ConnectionHandlerProc, &m_connections.back());
m_connections.back().m_htread = threads_helper::create_thread(ConnectionHandlerProc, &m_connections.back()); // ugh, seems very risky

return true;
}
Expand Down
1 change: 1 addition & 0 deletions src/cryptonote_protocol/block_queue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ void block_queue::add_blocks(uint64_t height, std::list<cryptonote::block_comple

void block_queue::add_blocks(uint64_t height, uint64_t nblocks, const boost::uuids::uuid &connection_id, boost::posix_time::ptime time)
{
CHECK_AND_ASSERT_THROW_MES(nblocks > 0, "Empty span");
boost::unique_lock<boost::recursive_mutex> lock(mutex);
blocks.insert(span(height, nblocks, connection_id, time));
}
Expand Down
6 changes: 6 additions & 0 deletions src/cryptonote_protocol/cryptonote_protocol_handler.inl
Original file line number Diff line number Diff line change
Expand Up @@ -1003,6 +1003,11 @@ skip:
MDEBUG(context << " next span in the queue has blocks " << start_height << "-" << (start_height + blocks.size() - 1)
<< ", we need " << previous_height);

if (blocks.empty())
{
MERROR("Next span has no blocks");
break;
}

block new_block;
if (!parse_and_validate_block_from_blob(blocks.front().block, new_block))
Expand Down Expand Up @@ -1498,6 +1503,7 @@ skip:

NOTIFY_REQUEST_CHAIN::request r = boost::value_initialized<NOTIFY_REQUEST_CHAIN::request>();
m_core.get_short_chain_history(r.block_ids);
CHECK_AND_ASSERT_MES(!r.block_ids.empty(), false, "Short chain history is empty");

if (!start_from_current_chain)
{
Expand Down
2 changes: 2 additions & 0 deletions src/mnemonics/electrum-words.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ namespace
*/
bool checksum_test(std::vector<std::string> seed, uint32_t unique_prefix_length)
{
if (seed.empty())
return false;
// The last word is the checksum.
std::string last_word = seed.back();
seed.pop_back();
Expand Down
11 changes: 8 additions & 3 deletions src/rpc/core_rpc_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,11 @@ namespace cryptonote
{
if (std::find(missed_txs.begin(), missed_txs.end(), h) == missed_txs.end())
{
if (txs.empty())
{
res.status = "Failed: internal error - txs is empty";
return true;
}
// core returns the ones it finds in the right order
if (get_transaction_hash(txs.front()) != h)
{
Expand Down Expand Up @@ -1150,7 +1155,7 @@ namespace cryptonote
error_resp.message = "Internal error: can't get block by hash. Hash = " + req.hash + '.';
return false;
}
if (blk.miner_tx.vin.front().type() != typeid(txin_gen))
if (blk.miner_tx.vin.size() != 1 || blk.miner_tx.vin.front().type() != typeid(txin_gen))
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
error_resp.message = "Internal error: coinbase transaction in the block has the wrong type";
Expand Down Expand Up @@ -1188,7 +1193,7 @@ namespace cryptonote
error_resp.message = "Internal error: can't get block by height. Height = " + boost::lexical_cast<std::string>(h) + ". Hash = " + epee::string_tools::pod_to_hex(block_hash) + '.';
return false;
}
if (blk.miner_tx.vin.front().type() != typeid(txin_gen))
if (blk.miner_tx.vin.size() != 1 || blk.miner_tx.vin.front().type() != typeid(txin_gen))
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
error_resp.message = "Internal error: coinbase transaction in the block has the wrong type";
Expand Down Expand Up @@ -1274,7 +1279,7 @@ namespace cryptonote
error_resp.message = "Internal error: can't get block by hash. Hash = " + req.hash + '.';
return false;
}
if (blk.miner_tx.vin.front().type() != typeid(txin_gen))
if (blk.miner_tx.vin.size() != 1 || blk.miner_tx.vin.front().type() != typeid(txin_gen))
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
error_resp.message = "Internal error: coinbase transaction in the block has the wrong type";
Expand Down
4 changes: 4 additions & 0 deletions src/rpc/daemon_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,10 @@ namespace rpc
}

header.hash = hash_in;
if (b.miner_tx.vin.size() != 1 || b.miner_tx.vin.front().type() != typeid(txin_gen))
{
return false;
}
header.height = boost::get<txin_gen>(b.miner_tx.vin.front()).height;

header.major_version = b.major_version;
Expand Down
4 changes: 2 additions & 2 deletions src/simplewallet/simplewallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4321,9 +4321,9 @@ bool simple_wallet::sweep_single(const std::vector<std::string> &args_)
fail_msg_writer() << tr("Multiple transactions are created, which is not supposed to happen");
return true;
}
if (ptx_vector[0].selected_transfers.size() > 1)
if (ptx_vector[0].selected_transfers.size() != 1)
{
fail_msg_writer() << tr("The transaction uses multiple inputs, which is not supposed to happen");
fail_msg_writer() << tr("The transaction uses multiple or no inputs, which is not supposed to happen");
return true;
}

Expand Down
1 change: 1 addition & 0 deletions src/wallet/wallet2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4950,6 +4950,7 @@ bool wallet2::tx_add_fake_output(std::vector<std::vector<tools::wallet2::get_out
if (global_index == real_index) // don't re-add real one
return false;
auto item = std::make_tuple(global_index, tx_public_key, mask);
CHECK_AND_ASSERT_MES(!outs.empty(), false, "internal error: outs is empty");
if (std::find(outs.back().begin(), outs.back().end(), item) != outs.back().end()) // don't add duplicates
return false;
outs.back().push_back(item);
Expand Down
7 changes: 7 additions & 0 deletions src/wallet/wallet_rpc_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,13 @@ namespace tools
uint64_t mixin = m_wallet->adjust_mixin(req.mixin);
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, req.priority, extra, req.account_index, req.subaddr_indices, m_trusted_daemon);

if (ptx_vector.empty())
{
er.code = WALLET_RPC_ERROR_CODE_TX_NOT_POSSIBLE;
er.message = "No transaction created";
return false;
}

// reject proposed transactions if there are more than one. see on_transfer_split below.
if (ptx_vector.size() != 1)
{
Expand Down

0 comments on commit 45a1c4c

Please sign in to comment.