Skip to content

Invalid stack addressing conversion

Moderate
hedgar2017 published GHSA-xxcp-xh65-6vjg Jun 27, 2024

Package

zksolc (Solidity)

Affected versions

<1.5.0

Patched versions

1.5.0

Description

Impact

We found a bug in EraVM LLVM back end leading to possible invalid stack access. This issue occurred because the addresses used to access the stack were not properly converted to cells, where each cell represents 32 bytes.
To convert stack accesses from byte addressing (emitted by LLVM) to cell addressing, we implemented the EraVMBytesToCells pass in LLVM. This pass detects stack accesses and converts them to cell addressing by generating a right shift by 5 (or a division by 32, which was generated in earlier versions of the compiler). However, if the address comes from the context.sp instruction, this conversion is not necessary as the address is already cell-addressed.

The issue here is that there was a lack of support for pseudo select instructions, which resulted in the generation of the following code where r3 and r2 are not cell-addressed:

add stack[r3], r0, r1
add.ne stack[r2], r0, r1

To address this issue, we have implemented support for pseudo select instructions that involve stack accesses. Additionally, we have marked the output register with IsEarlyClobber flag. This flag prevents the register allocator from assigning the same physical register to both the output register and the stack address register, ensuring proper expansion. As a result of these modifications, the following instructions are now being generated:

shr.s 5, r2, r2
shr.s 5, r3, r3
add stack[r3], r0, r1
add.ne stack[r2], r0, r1

Since we deal with a backend optimization bug, it’s hard to lift it to the language semantic and describe precisely which pieces of Vyper, Solidity and Yul are affected. To determine if a contract is affected by this bug, you will need to generate assembly file and look for the following code:

stack[rN] ; where rN is register and N can be a number from 1 to 15

If the definition of rN doesn’t come from the context.spshr.s 5, or div.s 32 instructions, it is likely that the bug exists in the contract.

Analysis has shown that no contracts were affected by the date of publishing this advisory.

Patches

Fixed in version 1.5.0.

Workarounds

Upgrading and redeploying affected contracts is the only way.

Severity

Moderate

CVE ID

CVE-2024-38533

Weaknesses

No CWEs