GHSA-6m97-7527-mh74 CVE-2023-46247 PYSEC-2023-307
incorrect storage layout for contracts containing large arrays
- Severity
- 7.5 / 10
- High · CVSS 3.1
- Exploit chance (EPSS)
- 0.69%
- Chance of exploitation in the next 30 days. Higher than 52.89% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Weakness
- CWE-193 Off-by-one Error
- Fix
0.3.8- Upgrade vyper to this version or later
Description
Impact
contracts containing large arrays might underallocate the number of slots they need. prior to v0.3.8, the calculation to determine how many slots a storage variable needed used math.ceil(type_.size_in_bytes / 32):
the intermediate floating point step can produce a rounding error if there are enough bits set in the IEEE-754 mantissa. roughly speaking, if type_.size_in_bytes is large (> 2**46), and slightly less than a power of 2, the calculation can overestimate how many slots are needed. if type_.size_in_bytes is slightly more than a power of 2, the calculation can underestimate how many slots are needed.
the following two example contracts can result in overwriting of the variable vulnerable:
large_array: address[2**64 + 1] # type_.size_in_bytes == 32 * (2**64 + 1); math.ceil(type_.size_in_bytes / 32) < 2**64 + 1
vulnerable: uint256
# writing to self.large_array[2**64] will overwrite self.vulnerable
large_dynarray: DynArray[address, 2**64] # Dynarray has a length word in front, its size in bytes is 32 * (2**64 + 1)
vulnerable: uint256
# writing to self.large_dynarray[2**64 - 1] will overwrite self.vulnerable
note that in the latter case, the risk of vulnerable being overwritten is relatively small, since it would cost roughly $1.45 million trillion USD at today's gas prices (gas price 20gwei, ETH ~= $1800) in order to extend the DynArray to its full container size.
Patches
patched by v0.3.8, specifically in commit https://github.com/vyperlang/vyper/commit/0bb7203b584e771b23536ba065a6efda457161bb.
Affected versions
PyPI
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
vyper PyPI → 0.3.8
- pip
pip install --upgrade "vyper>=0.3.8"- poetry
poetry add "vyper>=0.3.8"- uv
uv add "vyper>=0.3.8"
Severity breakdown
CVSS 3.1 7.5
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
- Attack vector
- Network
- Attack complexity
- Low
- Privileges required
- None
- User interaction
- None
- Scope
- Unchanged
- Confidentiality
- None
- Integrity
- High
- Availability
- None
Weakness
CWE-193: Off-by-one Error
A product calculates or uses an incorrect maximum or minimum value that is 1 more, or 1 less, than the correct value.
How to prevent it
- Implementation: When copying character arrays or using character manipulation methods, the correct size parameter must be used to account for the null terminator that needs to be added at the end of the array. Some examples of functions susceptible to this weakness in C include strcpy(), strncpy(), strcat(), strncat(), printf(), sprintf(), scanf() and sscanf().
References
Advisories
Packages
Other links
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| GHSA-2r3x-4mrv-mcxf Vyper: Memory corruption using function calls within tuples / nested calls | Medium | Also affects vyper |
| GHSA-4v7v-gqf9-ww2g Vyper: Call stack corruption when passing complex type containing non-base type members as argument | Medium | Also affects vyper |
| GHSA-vg88-3v92-rjx2 Vyper: Return inside for loop more than 1 level deep | Low | Also affects vyper |
| GHSA-3vcg-j39x-cwfm Vyper's `slice()` may elide side-effects when output length is 0 | Low | Also affects vyper |
| GHSA-qhr6-mgqr-mchm Vyper's `concat()` builtin may elide side-effects for zero-length arguments | Low | Also affects vyper |
| GHSA-h33q-mhmp-8p67 Vyper has a double eval in For List Iter | High | Also affects vyper |
| GHSA-4w26-8p97-f4jp AugAssign evaluation order causing OOB write within the object in Vyper | Critical | Also affects vyper |
| GHSA-2p94-8669-xg86 Vyper's sqrt doesn't define rounding behavior | High | Also affects vyper |
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor