target/riscv/cpu_helper.c: fix bad_shift in riscv_cpu_interrupt()
authorDaniel Henrique Barboza <dbarboza@ventanamicro.com>
Tue, 21 Jan 2025 18:48:47 +0000 (15:48 -0300)
committerAlistair Francis <alistair.francis@wdc.com>
Tue, 4 Mar 2025 05:42:54 +0000 (15:42 +1000)
Coverity reported a BAD_SHIFT issue in the following code:

 > 2097
 >>>>      CID 1590355:  Integer handling issues  (BAD_SHIFT)
 >>>>      In expression "hdeleg >> cause", right shifting by more than 63
       bits has undefined behavior.  The shift amount, "cause", is at least 64.
 > 2098         vsmode_exc = env->virt_enabled && (((hdeleg >> cause) & 1) || vs_injected);
 > 2099         /*

It is not clear to me how the tool guarantees that '"cause" is at least
64', but indeed there's no guarantees that it would be < 64 in the
'async = true' code path.

A simple fix to avoid a potential UB is to add a 'cause < 64' guard like
'mode' is already doing right before 'vsmode_exc'.

Resolves: Coverity CID 1590355
Fixes: 967760f62c ("target/riscv: Implement Ssdbltrp exception handling")
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250121184847.2109128-6-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
target/riscv/cpu_helper.c

index 8ff6d900f2c29696031241dafbb8c21d93fdaaa9..1de8e0e494719c8519a1278d8de69147d657c60b 100644 (file)
@@ -2084,7 +2084,9 @@ void riscv_cpu_do_interrupt(CPUState *cs)
     mode = env->priv <= PRV_S && cause < 64 &&
         (((deleg >> cause) & 1) || s_injected || vs_injected) ? PRV_S : PRV_M;
 
-    vsmode_exc = env->virt_enabled && (((hdeleg >> cause) & 1) || vs_injected);
+    vsmode_exc = env->virt_enabled && cause < 64 &&
+        (((hdeleg >> cause) & 1) || vs_injected);
+
     /*
      * Check double trap condition only if already in S-mode and targeting
      * S-mode