Summary
When using the built-in extract32(b, start)
, if the start
index provided has for side effect to update b
, the byte array to extract 32
bytes from, it could be that some dirty memory is read and returned by extract32
.
As of v0.4.0 (specifically, commit vyperlang/vyper@3d9c537), the compiler will panic instead of generating bytecode.
Details
Before evaluating start
, the function Extract32.build_IR
caches only:
but do not cache the actual content of b
. This means that if the evaluation of start
changes b
's content and length, an outdated length will be used with the new content when extracting 32 bytes from b
.
PoC
Calling the function foo
of the following contract returns b'uuuuuuuuuuuuuuuuuuuuuuuuuuu\x00\x00789'
meaning that extract32
accessed some dirty memory.
var:Bytes[96]
@internal
def bar() -> uint256:
self.var = b'uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu'
self.var = b''
return 3
@external
def foo() -> bytes32:
self.var = b'abcdefghijklmnopqrstuvwxyz123456789'
return extract32(self.var, self.bar(), output_type=bytes32)
# returns b'uuuuuuuuuuuuuuuuuuuuuuuuuuu\x00\x00789'
Impact
For contracts that are affected, it means that calling extract32
returns dirty memory bytes instead of some expected output.
References
Summary
When using the built-in
extract32(b, start)
, if thestart
index provided has for side effect to updateb
, the byte array to extract32
bytes from, it could be that some dirty memory is read and returned byextract32
.As of v0.4.0 (specifically, commit vyperlang/vyper@3d9c537), the compiler will panic instead of generating bytecode.
Details
Before evaluating
start
, the functionExtract32.build_IR
caches only:b
: https://github.com/vyperlang/vyper/blob/10564dcc37756f3d3684b7a91fd8f4325a38c4d8/vyper/builtins/functions.py#L916-L918b
: https://github.com/vyperlang/vyper/blob/10564dcc37756f3d3684b7a91fd8f4325a38c4d8/vyper/builtins/functions.py#L920-L922but do not cache the actual content of
b
. This means that if the evaluation ofstart
changesb
's content and length, an outdated length will be used with the new content when extracting 32 bytes fromb
.PoC
Calling the function
foo
of the following contract returnsb'uuuuuuuuuuuuuuuuuuuuuuuuuuu\x00\x00789'
meaning thatextract32
accessed some dirty memory.Impact
For contracts that are affected, it means that calling
extract32
returns dirty memory bytes instead of some expected output.References