GHSA-4w26-8p97-f4jpLow

AugAssign evaluation order causing OOB write within the object in Vyper

Published
February 21, 2025
Last Modified
April 9, 2025

🔗 CVE IDs covered (1)

📋 Description

Vyper handles AugAssign statements by first caching the target location to avoid double evaluation. However, in the case when target is an access to a DynArray and the rhs modifies the array, the cached target will evaluate first, and the bounds check will not be re-evaluated during the write portion of the statement. In other words, the following code

def poc():
    a: DynArray[uint256, 2] = [1, 2]
    a[1] += a.pop()

is equivalent to:

def poc():
    a: DynArray[uint256, 2] = [1, 2]
    a[1] += a[len(a) - 1]
    a.pop()

rather than:

def poc():
    a: DynArray[uint256, 2] = [1, 2]
    s: uint256 = a[1]
    t: uint256 = a.pop()
    a[1] = s + t  # reverts due to oob access

🎯 Affected products1

  • pip/vyper:<= 0.4.0

🔗 References (4)