Couple "Denial of Service" Vulnerabilities in Solana rBPF
Couple of bugs originating in Solana’s JIT: one an optimization issue, the other a bad instruction choice, both found through fuzzing.
Denial of Service - Resource Exhaustion ($100,000 bounty) the first bug was a memory leak from the following code:
entrypoint:
r0 = r0 + 255
if r0 <= 8355838 goto -2
r9 = r3 >> 3
call -1
What happens here is that the first two lines just iterate and add 255 to r0
to run for exactly 65534 instructions. Each Solana program is limited to only 65535 instructions. After that it does a calculation for the 65535th instruction, and then a call -1
which gives an unresolved symbol error as -1
isn’t a defined function. This error will allocate a buffer to store what the unresolved symbol was.
The problem is that the instruction count is only checked at the end of each basic block, so it checked and updated after the if
and added the call
. So after the call happens, the instruction count is updated. It sees that it has gone over 65535 instructions and issues a new error for exceeding the maximum instruction count. This new error overwrites the previously error, overwritting the pointer to the allocated buffer and never freeing it.
Persistent read-only data corruption
This one has a much simpler root cause, the cmp_immediate
instruction would use the x86 opcode 0x81
for all compares including 8bit wide compares, but 0x80
should be used for 8bit immediate. This would happen while looking up an offset to a memory address, and if some non-zero values were in the upper bits, the comparison could end up approving a write to a read-only memory location thinking it is intended for a different location.