Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Consolidated Security Fixes from 2.0.8 #9758

Merged
merged 1 commit into from
Dec 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ inline char* null_terminated_ptr_impl(uint64_t ptr)
"mov %[Ptr],%[Scratch]\n"
"1:\n" //start loop looking for either 0, or until we SEGV
"inc %[Scratch]\n"
"cmpb $0,%%gs:(%[Scratch])\n"
"cmpb $0,%%gs:-1(%[Scratch])\n"
"jne 1b\n"
"2:\n"
"add %%gs:%c[linearMemoryStart], %[Ptr]\n" //add address of linear memory 0 to ptr
Expand Down
6 changes: 4 additions & 2 deletions libraries/chain/transaction_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,10 @@ namespace eosio { namespace chain {
}

if( !explicit_billed_cpu_time ) {
// if account no longer has enough cpu to exec trx, don't try
validate_account_cpu_usage( billed_cpu_time_us, account_cpu_limit, true );
// Fail early if amount of the previous speculative execution is within 10% of remaining account cpu available
int64_t validate_account_cpu_limit = account_cpu_limit - EOS_PERCENT( account_cpu_limit, 10 * config::percent_1 );
if( validate_account_cpu_limit < 0 ) validate_account_cpu_limit = 0;
validate_account_cpu_usage( billed_cpu_time_us, validate_account_cpu_limit, true );
}

eager_net_limit = (eager_net_limit/8)*8; // Round down to nearest multiple of word size (8 bytes) so check_net_usage can be efficient
Expand Down
15 changes: 13 additions & 2 deletions plugins/producer_plugin/producer_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1706,15 +1706,23 @@ bool producer_plugin_impl::process_unapplied_trxs( const fc::time_point& deadlin
const transaction_metadata_ptr trx = itr->trx_meta;
++num_processed;
try {
auto trx_deadline = fc::time_point::now() + fc::milliseconds( _max_transaction_time_ms );
auto start = fc::time_point::now();
auto trx_deadline = start + fc::milliseconds( _max_transaction_time_ms );

auto prev_billed_cpu_time_us = trx->billed_cpu_time_us;
if( prev_billed_cpu_time_us > 0 ) {
auto prev_billed_plus50 = prev_billed_cpu_time_us + EOS_PERCENT( prev_billed_cpu_time_us, 50 * config::percent_1 );
auto trx_dl = start + fc::microseconds( prev_billed_plus50 );
if( trx_dl < trx_deadline ) trx_deadline = trx_dl;
}
bool deadline_is_subjective = false;
if( _max_transaction_time_ms < 0 ||
(_pending_block_mode == pending_block_mode::producing && deadline < trx_deadline) ) {
deadline_is_subjective = true;
trx_deadline = deadline;
}

auto trace = chain.push_transaction( trx, trx_deadline, trx->billed_cpu_time_us, false );
auto trace = chain.push_transaction( trx, trx_deadline, prev_billed_cpu_time_us, false );
if( trace->except ) {
if( exception_is_exhausted( *trace->except, deadline_is_subjective ) ) {
if( block_is_exhausted() ) {
Expand All @@ -1725,6 +1733,9 @@ bool producer_plugin_impl::process_unapplied_trxs( const fc::time_point& deadlin
// don't erase, subjective failure so try again next time
} else {
// this failed our configured maximum transaction time, we don't want to replay it
fc_dlog( _log, "Failed ${c} trx, prev billed: ${p}us, ran: ${r}us, id: ${id}",
("c", trace->except->code())("p", prev_billed_cpu_time_us)
("r", fc::time_point::now() - start)("id", trx->id()) );
++num_failed;
if( itr->next ) itr->next( trace );
itr = _unapplied_transactions.erase( itr );
Expand Down
1 change: 1 addition & 0 deletions unittests/wasm_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1990,6 +1990,7 @@ BOOST_AUTO_TEST_CASE( billed_cpu_test ) try {
chain.produce_block( fc::days(1) ); // produce for one day to reset account cpu

cpu_limit = mgr.get_account_cpu_limit_ex(acc).first.max;
cpu_limit -= EOS_PERCENT( cpu_limit, 10 * config::percent_1 ); // transaction_context verifies within 10%, so subtract 10% out

ptrx = create_trx(0);
BOOST_CHECK_LT( cpu_limit+1, max_cpu_time_us ); // needs to be less or this just tests the same thing as max_cpu_time_us test above
Expand Down