target/i386: Check privilege level for protected mode 'int N' task gate
commit3df1a3d070575419859cbbab1083fafa7ec2669a
authorPeter Maydell <peter.maydell@linaro.org>
Sat, 21 Nov 2020 22:44:45 +0000 (21 22:44 +0000)
committerPaolo Bonzini <pbonzini@redhat.com>
Sat, 2 Jan 2021 20:03:09 +0000 (2 21:03 +0100)
treeca1bbf1d841cb7606ac161be66970acf492ecc9a
parent63f957ac96eba545ef60abebfc6741d06fd99ade
target/i386: Check privilege level for protected mode 'int N' task gate

When the 'int N' instruction is executed in protected mode, the
pseudocode in the architecture manual specifies that we need to check:

 * vector number within IDT limits
 * selected IDT descriptor is a valid type (interrupt, trap or task gate)
 * if this was a software interrupt then gate DPL < CPL

The way we had structured the code meant that the privilege check for
software interrupts ended up not in the code path taken for task gate
handling, because all of the task gate handling code was in the 'case 5'
of the switch which was checking "is this descriptor a valid type".

Move the task gate handling code out of that switch (so that it is now
purely doing the "valid type?" check) and below the software interrupt
privilege check.

The effect of this missing check was that in a guest userspace binary
executing 'int 8' would cause a guest kernel panic rather than the
userspace binary being handed a SEGV.

This is essentially the same bug fixed in VirtualBox in 2012:
https://www.halfdog.net/Security/2012/VirtualBoxSoftwareInterrupt0x8GuestCrash/

Note that for QEMU this is not a security issue because it is only
present when using TCG.

Fixes: https://bugs.launchpad.net/qemu/+bug/1813201
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20201121224445.16236-1-peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
target/i386/tcg/seg_helper.c