According to the RISC-V smcdeleg specification: "When menvcfg.CDE=0,
attempts to access scountinhibit raise an illegal-instruction
exception."

The current implementation of scountinhibit_pred() only checks the
hardware extensions (ext_ssccfg, ext_smcdeleg) and virtualization
status, but completely misses the runtime environment configuration
check (menvcfg.CDE).  This allows S-mode to access scountinhibit even
when the M-mode has explicitly disabled counter delegation.

This issue was discovered by the SpecHunter tool
(https://github.com/yizishun/rv-isa-sec/blob/master/output/riscv-isa-manual/pr-2571/qemu.txt).

Fixes: 6247dc2ef70b ("target/riscv: Add counter delegation/configuration 
support")
Signed-off-by: Zishun Yi <[email protected]>
---
v2: Removed mistakenly added #include "cpu_bits.h".

 target/riscv/csr.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index da366cf56271..9ae8d553dcf1 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -398,6 +398,10 @@ static RISCVException scountinhibit_pred(CPURISCVState 
*env, int csrno)
         return RISCV_EXCP_ILLEGAL_INST;
     }
 
+    if (!get_field(env->menvcfg, MENVCFG_CDE)) {
+        return RISCV_EXCP_ILLEGAL_INST;
+    }
+
     if (env->virt_enabled) {
         return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
     }
-- 
2.51.2


Reply via email to