Attackathon _ Fuel Network 33203 - [Smart Contract - Insight] function inlining doesnt consider asm
Submitted on Sun Jul 14 2024 08:24:19 GMT-0400 (Atlantic Standard Time) by @cyberthirst for Attackathon | Fuel Network
Report ID: #33203
Report type: Smart Contract
Report severity: Insight
Target: https://github.com/FuelLabs/sway/tree/v0.61.2
Impacts:
Compiler bug
Description
Brief/Intro
The Sway compiler employs function inlining optimization. To be inlined, a function must meet certain criteria. If the function is called more than once, it must be smaller than 4 instructions. The compiler considers the asm instruction as one, although the asm instruction itself can contain tens of instructions. As such, this heuristic can lead to contract size bloating because it can inline very big functions.
Vulnerability Details
Consider the code from 1 of the inline heuristic:
As can be seen, we require the instruction size to be maximally 4 instructions. However, the InstOp::AsmBlock
counts as one. So if we consider the function testf
from the PoC, it "consists" of only 2 instructions. However, the ASM block consists of an additional 55 instructions.
As such, even big functions, i.e., such functions that contain big ASM blocks, are inlined.
Impact Details
Excessive inlining can lead to various problems. Firstly, it can greatly increase contract deployment costs. Secondly, it leads to the bloating of the VM's memory, and as such, the memory size limit will be hit more easily.
References
Proof of concept
Proof of Concept
The following PoC shows that the function testf
, which contains a very big asm block, gets inlined in all the 3 functions that call it and thus leads to contract size bloat.
If we run forc build --release --ir final | grep -n "asm(r1, r2)"
the output is:
which demonstrates that the function testf
was inlined 3 times.
src/main.sw:
forc.toml
Last updated