helper_ret_protected only checks if the VM flag is set in the new eflags,
while the Intel manual says:
IF tempEFLAGS(VM) = 1 and CPL = 0
THEN GOTO RETURN-TO-VIRTUAL-8086-MODE;
As CPL==0 check is missing in QEMU TCG, a 32-bit binary inside the guest
can elevate privileges by executing an iret and returning to VM86 while
setting IOPL to 3.
Fixes: 90a9fdae1f1a ("more ring 0 operations")
Signed-off-by: Hrvoje Misetic <misetic@osec.io>
---
target/i386/tcg/seg_helper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c
index 58aac72011..57cf668131 100644
--- a/target/i386/tcg/seg_helper.c
+++ b/target/i386/tcg/seg_helper.c
@@ -2068,7 +2068,7 @@ static inline void helper_ret_protected(CPUX86State *env, int shift,
new_cs = popl(&sa) & 0xffff;
if (is_iret) {
new_eflags = popl(&sa);
- if (new_eflags & VM_MASK) {
+ if (new_eflags & VM_MASK && cpl == 0) {
goto return_to_vm86;
}
}
--
2.48.1