Overview
In Solana rBPF versions 0.2.26 and 0.2.27 are affected by Incorrect Calculation which is caused by improper implementation of sdiv instruction. This can lead to the wrong execution path, resulting in huge loss in specific cases. For example, the result of a sdiv instruction may decide whether to transfer tokens or not. The vulnerability affects both integrity and may cause serious availability problems.
Details
rbpf, which is the bpf VM for executing Solana programs, introduces a new instruction (i.e., signed division). However, the instruction is not correctly implemented in JIT mode, which is used by most of the validators. Specifically, the sdiv instruction does not consider the signed bit while extending from 32 bit to 64 bit in JIT mode. This can influence the execution logic of the deployed programs consisting of sdiv instruction.
PoC Details
Running the code under JIT and interpreted mode, you can see in the interpreted mode that register r5 is set to 0xFFFFFFFFFFFFFFFD, while in JIT mode, r5 is set to 0x00000000FFFFFFFD. The signed bit of R5 in JIT mode is not set correctly, leading to the wrong result of the division signed instruction.
Note: You should run the code in the first part of the POC Code section. The second part is the byte-code representation of what is actually executed with the code you just ran.
PoC Code
Load byte-code poc:
let mut executable_raw = Executable::<UserError, TestInstructionMeter>::from_text_bytes(
program,
Some(check),
config,
SyscallRegistry::default(),
bpf_functions,
);
The disassembled code:
entrypoint:
tlddw r5, 0x10000000c
sdiv32 r5, -4
jslt r5, 0, lbb_7
lddw r0, 0x1
exit
lbb_7:
texit
Affected Environments
0.2.26 and 0.2.27
Prevention
Upgrade version to 0.2.28 or higher