https://bugs.kde.org/show_bug.cgi?id=509157
Bug ID: 509157
Summary: riscv64: shift instructions can behave wrong
Classification: Developer tools
Product: valgrind
Version First unspecified
Reported In:
Platform: Ubuntu
OS: Linux
Status: REPORTED
Severity: normal
Priority: NOR
Component: vex
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: ---
SUMMARY
The RISCV64 ISA specifications say that the shift operations:
- sra, srl, sll use the lowest 6 bits of rd2
- sraw, srlw, sllw use the lowest 5 bits of rd2
as amount to shift by.
(Can be found in the RISCV unprivileged manual, chapter 4.2.1. Integer
Register-Immediate Instructions)
In `VEX/priv/guest_riscv64_toIR.c` lines 1534-1579 and lines 1713-1740 these
shift instructions are decoded, but the lowest 8 bits of rs2 are taken as
parameter for the shift.
This can result in shifts by more than 63 for sra, srl, sll and more than 31
for raw, srlw, sllw.
This was found while using angr (with pyvex for lifting), so there is no crash.
STEPS TO REPRODUCE
angr reproducer: https://github.com/Cskorpion/angr-shift-reproducer
OBSERVED RESULT
z3 formula for register x7 when executing the riscv instruction 0x41b5d3b3 (sra
x7, x11, x27) with angr:
reg_x11_9_64 >> Concat(0, Extract(7, 0, reg_x27_8_64))
EXPECTED RESULT
reg_x11_9_64 >> Concat(0, Extract(5, 0, reg_x27_8_64))
ADDITIONAL INFORMATION
Fix this issue by replacing `unop(Iop_64to8, getIReg64(rs2))` in corresponding
lines with
- 'binop(Iop_And8, mkU8(0b00111111), unop(Iop_64to8, getIReg64(rs2)))' for sra,
srl, sll
- 'binop(Iop_And8, mkU8(0b00011111), unop(Iop_64to8, getIReg64(rs2)))' for
sraw, srlw, sllw
--
You are receiving this mail because:
You are watching all bug changes.