[PATCH] target/i386: Add missing CPL==0 check when returning to VM86

Hrvoje Misetic posted 1 patch 2 days, 5 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260528113808.86036-1-misetic@osec.io
Maintainers: Paolo Bonzini <pbonzini@redhat.com>, Richard Henderson <richard.henderson@linaro.org>
target/i386/tcg/seg_helper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH] target/i386: Add missing CPL==0 check when returning to VM86
Posted by Hrvoje Misetic 2 days, 5 hours ago
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