#38682 [SC-Medium] AugAssign evaluation order causing OOB write within the object
Submitted on Jan 10th 2025 at 01:15:10 UTC by @anatomist for Attackathon | Ethereum Protocol
Report ID: #38682
Report Type: Smart Contract
Report severity: Medium
Target: https://github.com/vyperlang/vyper
Impacts:
(Compiler) Incorrect bytecode generation leading to incorrect behavior
(Compiler) Unexpected behavior
Description
Brief/Intro
AugAssign (e.g. +=
, -=
, ...) statements does not consider the side effect caused by rhs, allowing out-of-bounds index write within the array.
Vulnerability Details
Vyper parse AugAssign
statements by first cache the target location to avoid double evaluation.
However, in the case when target is an access to a DynArray
and the right value modify the array, the cached target
will evaluate first, following the modifications like DynArray.pop()
, and eventually the STORE
operation could store the computed output in an index that falls outside the array’s current length bounds.
This is alike this high severity issue where it discusses similar issues for Assign
. However, it is not appropriate to apply the same mitigations in parse_Assign
to parse_AugAssign
, since the evaluation order of Assign
is rhs -> lhs
, while evaluation of AugAssign
should be dereference lhs -> rhs -> assign to lhs
, so assigning rhs
to a temporary variable will actually change the evaluation order. We currently don't have a simple patch in mind, aside from reimplementing the entire AugAssign
. Notably, care must be taken to not double evaluate lhs
when fixing the bug.
Impact Details
The direct impact is out-of-bounds index access within the array. But wrong IR code emission could also lead to various consequences.
References
https://github.com/vyperlang/vyper/blob/a29b49d422f6979be2b9c6c80aa583a60b1ccb7f/vyper/codegen/stmt.py#L291
Proof of Concept
Proof of Concept
Was this helpful?