Impact
the slice()
builtin can elide side effects when the output length is 0, and the source bytestring is a builtin (msg.data
or <address>.code
). the reason is that for these source locations, the check that length >= 1
is skipped:
|
if not is_adhoc_slice: |
|
if length_literal is not None: |
|
if length_literal < 1: |
|
raise ArgumentException("Length cannot be less than 1", length_expr) |
|
|
the result is that a 0-length bytestring constructed with slice can be passed to make_byte_array_copier
, which elides evaluation of its source argument when the max length is 0:
|
if src.value == "~empty" or src.typ.maxlen == 0: |
|
# set length word to 0. |
|
return STORE(dst, 0) |
the impact is that side effects in the start
argument may be elided when the length
argument is 0, e.g. slice(msg.data, self.do_side_effect(), 0)
.
the following example illustrates how the issue would look in user code
counter: public(uint256)
@external
def test() -> Bytes[10]:
b: Bytes[10] = slice(msg.data, self.side_effect(), 0)
return b
def side_effect() -> uint256:
self.counter += 1
return 0
the severity assigned is low, since this is not a very useful pattern and unlikely to be found in user code.
Patches
the fix is tracked in #4645, which disallows any invocation of slice()
with length 0, including for the ad hoc locations discussed in this advisory.
Workarounds
Is there a way for users to fix or remediate the vulnerability without upgrading?
References
Are there any links users can visit to find out more?
Impact
the
slice()
builtin can elide side effects when the output length is 0, and the source bytestring is a builtin (msg.data
or<address>.code
). the reason is that for these source locations, the check thatlength >= 1
is skipped:vyper/vyper/builtins/functions.py
Lines 315 to 319 in 68b68c4
the result is that a 0-length bytestring constructed with slice can be passed to
make_byte_array_copier
, which elides evaluation of its source argument when the max length is 0:vyper/vyper/codegen/core.py
Lines 189 to 191 in 68b68c4
the impact is that side effects in the
start
argument may be elided when thelength
argument is 0, e.g.slice(msg.data, self.do_side_effect(), 0)
.the following example illustrates how the issue would look in user code
the severity assigned is low, since this is not a very useful pattern and unlikely to be found in user code.
Patches
the fix is tracked in #4645, which disallows any invocation of
slice()
with length 0, including for the ad hoc locations discussed in this advisory.Workarounds
Is there a way for users to fix or remediate the vulnerability without upgrading?
References
Are there any links users can visit to find out more?