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.

Reply via email to