Correctly reject invalid segment registers, including CS when used as
the destination of a MOV. Ignore the REX prefix as well.
Fixes: 5e9e21bcc4d ("target/i386: move 60-BF opcodes to new decoder",
2024-05-07)
Cc: [email protected]
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3195
Signed-off-by: Paolo Bonzini <[email protected]>
---
target/i386/tcg/decode-new.c.inc | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc
index 805cfd08e83..0f8c5d16938 100644
--- a/target/i386/tcg/decode-new.c.inc
+++ b/target/i386/tcg/decode-new.c.inc
@@ -2059,7 +2059,12 @@ static bool decode_op(DisasContext *s, CPUX86State *env,
X86DecodedInsn *decode,
case X86_TYPE_S: /* reg selects a segment register */
op->unit = X86_OP_SEG;
- goto get_reg;
+ op->n = (get_modrm(s, env) >> 3) & 7;
+ /* Values outside [CDEFGS]S, as well as storing to CS, are invalid. */
+ if (op->n >= 6 || (op->n == R_CS && op == &decode->op[0])) {
+ return false;
+ }
+ break;
case X86_TYPE_P:
op->unit = X86_OP_MMX;
--
2.51.1