Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.

Commit ae68dc3

Browse files
committed
EIP-211 updates
1 parent 4a1f205 commit ae68dc3

File tree

4 files changed

+24
-0
lines changed

4 files changed

+24
-0
lines changed

ethcore/src/evm/evm.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ pub enum Error {
6464
BuiltIn(&'static str),
6565
/// When execution tries to modify the state in static context
6666
MutableCallInStaticContext,
67+
/// Out of bounds access in RETURNDATACOPY.
68+
OutOfBounds,
6769
/// Likely to cause consensus issues.
6870
Internal(String),
6971
}
@@ -85,6 +87,7 @@ impl fmt::Display for Error {
8587
use self::Error::*;
8688
match *self {
8789
OutOfGas => write!(f, "Out of gas"),
90+
OutOfBounds => write!(f, "Out of bounds"),
8891
BadJumpDestination { destination } => write!(f, "Bad jump destination {:x}", destination),
8992
BadInstruction { instruction } => write!(f, "Bad instruction {:x}", instruction),
9093
StackUnderflow { instruction, wanted, on_stack } => write!(f, "Stack underflow {} {}/{}", instruction, wanted, on_stack),

ethcore/src/evm/interpreter/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,9 @@ impl<Cost: CostType> Interpreter<Cost> {
296296
let contract_code = self.mem.read_slice(init_off, init_size);
297297
let can_create = ext.balance(&params.address)? >= endowment && ext.depth() < ext.schedule().max_depth;
298298

299+
// clear return data buffer before crearing new call frame.
300+
self.return_data = ReturnData::empty();
301+
299302
if !can_create {
300303
stack.push(U256::zero());
301304
return Ok(InstructionResult::UnusedGas(create_gas));
@@ -353,6 +356,9 @@ impl<Cost: CostType> Interpreter<Cost> {
353356
_ => panic!(format!("Unexpected instruction {} in CALL branch.", instruction))
354357
};
355358

359+
// clear return data buffer before crearing new call frame.
360+
self.return_data = ReturnData::empty();
361+
356362
let can_call = has_balance && ext.depth() < ext.schedule().max_depth;
357363
if !can_call {
358364
stack.push(U256::zero());
@@ -514,6 +520,14 @@ impl<Cost: CostType> Interpreter<Cost> {
514520
Self::copy_data_to_memory(&mut self.mem, stack, params.data.as_ref().map_or_else(|| &[] as &[u8], |d| &*d as &[u8]));
515521
},
516522
instructions::RETURNDATACOPY => {
523+
{
524+
let source_offset = stack.peek(1);
525+
let size = stack.peek(2);
526+
let return_data_len = U256::from(self.return_data.len());
527+
if source_offset <= &return_data_len && source_offset.overflow_add(*size).0 <= return_data_len {
528+
return Err(evm::Error::OutOfBounds);
529+
}
530+
}
517531
Self::copy_data_to_memory(&mut self.mem, stack, &*self.return_data);
518532
},
519533
instructions::CODECOPY => {

ethcore/src/executive.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
562562
| Err(evm::Error::BuiltIn {..})
563563
| Err(evm::Error::OutOfStack {..})
564564
| Err(evm::Error::MutableCallInStaticContext)
565+
| Err(evm::Error::OutOfBounds)
565566
| Ok(FinalizationResult { apply_state: false, .. }) => {
566567
self.state.revert_to_checkpoint();
567568
},

ethcore/src/types/trace_types/error.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ pub enum Error {
4242
Internal,
4343
/// When execution tries to modify the state in static context
4444
MutableCallInStaticContext,
45+
/// Contract tried to access past the return data buffer.
46+
OutOfBounds,
4547
}
4648

4749
impl<'a> From<&'a EvmError> for Error {
@@ -55,6 +57,7 @@ impl<'a> From<&'a EvmError> for Error {
5557
EvmError::BuiltIn { .. } => Error::BuiltIn,
5658
EvmError::Internal(_) => Error::Internal,
5759
EvmError::MutableCallInStaticContext => Error::MutableCallInStaticContext,
60+
EvmError::OutOfBounds => Error::OutOfBounds,
5861
}
5962
}
6063
}
@@ -77,6 +80,7 @@ impl fmt::Display for Error {
7780
BuiltIn => "Built-in failed",
7881
Internal => "Internal error",
7982
MutableCallInStaticContext => "Mutable Call In Static Context",
83+
OutOfBounds => "Out of bounds",
8084
};
8185
message.fmt(f)
8286
}
@@ -94,6 +98,7 @@ impl Encodable for Error {
9498
Internal => 5,
9599
BuiltIn => 6,
96100
MutableCallInStaticContext => 7,
101+
OutOfBounds => 8,
97102
};
98103

99104
s.append_internal(&value);
@@ -113,6 +118,7 @@ impl Decodable for Error {
113118
5 => Ok(Internal),
114119
6 => Ok(BuiltIn),
115120
7 => Ok(MutableCallInStaticContext),
121+
8 => Ok(OutOfBounds),
116122
_ => Err(DecoderError::Custom("Invalid error type")),
117123
}
118124
}

0 commit comments

Comments
 (0)