Skip to content
This repository has been archived by the owner on Nov 15, 2021. It is now read-only.

Commit

Permalink
[re-create] Add BigInteger sanity checks for VM (#676)
Browse files Browse the repository at this point in the history
  • Loading branch information
ixje authored Oct 20, 2018
1 parent 1b6b4a0 commit 5088db5
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ All notable changes to this project are documented in this file.

[0.8.2] In Progress
-------------------
- Add VM sanity checks for operations on ``BigInteger``'s
- Add raw transaction building examples in ``\examples\`` folder
- Add ExtendedJsonRpcApi, Add ``getnodestate`` RPC extended method, Add ``gettxhistory`` RPC extended method
- Fix return types of ``claimGas`` function.
Expand Down
95 changes: 94 additions & 1 deletion neo/SmartContract/ApplicationEngine.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class ApplicationEngine(ExecutionEngine):

maxItemSize = 1024 * 1024
maxArraySize = 1024
max_shl_shr = 65535 # ushort.maxValue
min_shl_shr = -65535 # -ushort.maxValue
MaxSizeForBigInteger = 32

def GasConsumed(self):
return Fixed8(self.gas_consumed)
Expand Down Expand Up @@ -116,6 +119,91 @@ def CheckInvocationStack(self):

return True

def _checkBigInteger(self, value):
return len(value.ToByteArray()) <= self.MaxSizeForBigInteger

def CheckBigIntegers(self):
cx = self.CurrentContext
opcode = cx.NextInstruction

if opcode == OpCode.SHL:
ishift = cx.EvaluationStack.Peek(0).GetBigInteger()

if ishift > self.max_shl_shr or ishift < self.min_shl_shr:
return False

x = cx.EvaluationStack.Peek(1).GetBigInteger()

try:
if not self._checkBigInteger(x << ishift):
return False
except ValueError:
# negative ishift throws a value error
return False

if opcode == OpCode.SHR:
ishift = cx.EvaluationStack.Peek(0).GetBigInteger()

if ishift > self.max_shl_shr or ishift < self.min_shl_shr:
return False

x = cx.EvaluationStack.Peek(1).GetBigInteger()

try:
if not self._checkBigInteger(x >> ishift):
return False
except ValueError:
# negative ishift throws a value error
return False

if opcode == OpCode.INC:
x = cx.EvaluationStack.Peek().GetBigInteger()
if not self._checkBigInteger(x) or not self._checkBigInteger(x + 1):
return False

if opcode == OpCode.DEC:
x = cx.EvaluationStack.Peek().GetBigInteger()
if not self._checkBigInteger(x) or (x.Sign <= 0 and not self._checkBigInteger(x - 1)):
return False

if opcode == OpCode.ADD:
x2 = cx.EvaluationStack.Peek().GetBigInteger()
x1 = cx.EvaluationStack.Peek(1).GetBigInteger()

if not self._checkBigInteger(x2) or not self._checkBigInteger(x1) or not self._checkBigInteger(x1 + x2):
return False

if opcode == OpCode.SUB:
x2 = cx.EvaluationStack.Peek().GetBigInteger()
x1 = cx.EvaluationStack.Peek(1).GetBigInteger()

if not self._checkBigInteger(x2) or not self._checkBigInteger(x1) or not self._checkBigInteger(x1 - x2):
return False

if opcode == OpCode.MUL:
x2 = cx.EvaluationStack.Peek().GetBigInteger()
x1 = cx.EvaluationStack.Peek(1).GetBigInteger()

length_x1 = len(x1.ToByteArray())
if length_x1 > self.MaxSizeForBigInteger:
return False

length_x2 = len(x2.ToByteArray())
if length_x2 > self.MaxSizeForBigInteger:
return False

if length_x1 + length_x2 > self.MaxSizeForBigInteger:
return False

if opcode in [OpCode.DIV, OpCode.MOD]:
x2 = cx.EvaluationStack.Peek().GetBigInteger()
x1 = cx.EvaluationStack.Peek(1).GetBigInteger()

if not self._checkBigInteger(x2) or not self._checkBigInteger(x1):
return False

return True

def CheckItemSize(self):

cx = self.CurrentContext
Expand Down Expand Up @@ -307,7 +395,12 @@ def loop_validation_and_stepinto():
return False

if not self.CheckInvocationStack():
logger.debug("INVOCATION SIZE TO BIIG")
logger.debug("INVOCATION SIZE TO BIG")
self._VMState |= VMState.FAULT
return False

if not self.CheckBigIntegers():
logger.debug("BigIntegers check failed")
self._VMState |= VMState.FAULT
return False

Expand Down

0 comments on commit 5088db5

Please sign in to comment.