CVE-2024-32649
vyper performs multiple eval of `sqrt()` argument built in
描述
### Summary Using the `sqrt` builtin can result in multiple eval evaluation of side effects when the argument has side-effects. The bug is more difficult (but not impossible!) to trigger as of 0.3.4, when the unique symbol fence was introduced (https://github.com/vyperlang/vyper/pull/2914). A contract search was performed and no vulnerable contracts were found in production. ### Details It can be seen that the `build_IR` function of the `sqrt` builtin doesn't cache the argument to the stack: https://github.com/vyperlang/vyper/blob/4595938734d9988f8e46e8df38049ae0559abedb/vyper/builtins/functions.py#L2151 As such, it can be evaluated multiple times (instead of retrieving the value from the stack). ### PoC With at least Vyper version `0.2.15+commit.6e7dba7` the following contract: ```vyper c: uint256 @internal def some_decimal() -> decimal: self.c += 1 return 1.0 @external def foo() -> uint256: k: decimal = sqrt(self.some_decimal()) return self.c ``` passes the following test: ```solidity // SPDX-License-Identifier: MIT pragma solidity >=0.8.13; import "../../lib/ds-test/test.sol"; import "../../lib/utils/Console.sol"; import "../../lib/utils/VyperDeployer.sol"; import "../ITest.sol"; contract ConTest is DSTest { VyperDeployer vyperDeployer = new VyperDeployer(); ITest t; function setUp() public { t = ITest(vyperDeployer.deployContract("Test")); } function testFoo() public { uint256 val = t.foo(); console.log(val); assert (val == 4); } } ``` ### Patches Patched in https://github.com/vyperlang/vyper/pull/3976. ### Impact No vulnerable production contracts were found.
如何修補 CVE-2024-32649
要修補 CVE-2024-32649,請將受影響套件升級到下列已修補版本。
- —升級至 0.4.0 或更新版本
- —升級至 0.4.0 或更新版本
CVE-2024-32649 正在被利用嗎?
低 — EPSS 為 0.8%,目前沒有觀察到大規模利用活動。