The _bytes_to_num() function used in conversion assumes that any bytestring types are in memory. If they are declared from within the expression, it will try to load them from memory and panic.
Vulnerability Details
When converting a bytestring to a number, we perform the following:
The get_bytearray_length() function correctly handles the case when an empty bytestring is passed directly to the conversion. However, the bytes_data_ptr() function panics if the argument doesn't have a location specified:
if ptr.location is None:
raise CompilerPanic("tried to modify non-pointer type")
Error compiling: examples/minimal.vy
vyper.exceptions.CompilerPanic: tried to modify non-pointer type
Impact
Contracts that include a conversion where an empty bytestring is declared within the expression will fail to compile.
Tools Used
Manual Review
Recommendations
Use something like the ensure_in_memory() function used elsewhere in the compiler to move empty bytestrings to memory before converting them, or create a manual override for empty strings to return the appropriate value.
Submitted by obront.
Relevant GitHub Links
https://github.com/vyperlang/vyper/blob/b01cd686aa567b32498fefd76bd96b0597c6f099/vyper/builtins/_convert.py#L76-L85
Summary
The
_bytes_to_num()
function used in conversion assumes that any bytestring types are in memory. If they are declared from within the expression, it will try to load them from memory and panic.Vulnerability Details
When converting a bytestring to a number, we perform the following:
The
get_bytearray_length()
function correctly handles the case when an empty bytestring is passed directly to the conversion. However, thebytes_data_ptr()
function panics if the argument doesn't have alocation
specified:Proof of Concept
The following Vyper contract should compile:
However, it instead returns the following:
Impact
Contracts that include a conversion where an empty bytestring is declared within the expression will fail to compile.
Tools Used
Manual Review
Recommendations
Use something like the
ensure_in_memory()
function used elsewhere in the compiler to move empty bytestrings to memory before converting them, or create a manual override for empty strings to return the appropriate value.