[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 15/55] target/i386: Check privilege level for protected mode 'int
From: |
Paolo Bonzini |
Subject: |
[PULL 15/55] target/i386: Check privilege level for protected mode 'int N' task gate |
Date: |
Mon, 21 Dec 2020 15:44:07 +0100 |
From: Peter Maydell <peter.maydell@linaro.org>
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 | 35 +++++++++++++++++++++--------------
1 file changed, 21 insertions(+), 14 deletions(-)
diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c
index 1255efe7e0..5f2ee6aa7e 100644
--- a/target/i386/tcg/seg_helper.c
+++ b/target/i386/tcg/seg_helper.c
@@ -634,6 +634,24 @@ static void do_interrupt_protected(CPUX86State *env, int
intno, int is_int,
type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;
switch (type) {
case 5: /* task gate */
+ case 6: /* 286 interrupt gate */
+ case 7: /* 286 trap gate */
+ case 14: /* 386 interrupt gate */
+ case 15: /* 386 trap gate */
+ break;
+ default:
+ raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);
+ break;
+ }
+ dpl = (e2 >> DESC_DPL_SHIFT) & 3;
+ cpl = env->hflags & HF_CPL_MASK;
+ /* check privilege if software int */
+ if (is_int && dpl < cpl) {
+ raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);
+ }
+
+ if (type == 5) {
+ /* task gate */
/* must do that check here to return the correct error code */
if (!(e2 & DESC_P_MASK)) {
raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2);
@@ -661,21 +679,10 @@ static void do_interrupt_protected(CPUX86State *env, int
intno, int is_int,
SET_ESP(esp, mask);
}
return;
- case 6: /* 286 interrupt gate */
- case 7: /* 286 trap gate */
- case 14: /* 386 interrupt gate */
- case 15: /* 386 trap gate */
- break;
- default:
- raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);
- break;
- }
- dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- cpl = env->hflags & HF_CPL_MASK;
- /* check privilege if software int */
- if (is_int && dpl < cpl) {
- raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);
}
+
+ /* Otherwise, trap or interrupt gate */
+
/* check valid bit */
if (!(e2 & DESC_P_MASK)) {
raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2);
--
2.29.2
- [PULL 31/55] meson: cleanup Kconfig.host handling, (continued)
- [PULL 31/55] meson: cleanup Kconfig.host handling, Paolo Bonzini, 2020/12/21
- [PULL 38/55] curl: convert to meson, Paolo Bonzini, 2020/12/21
- [PULL 11/55] configure: document --without-default-{features, devices}, Paolo Bonzini, 2020/12/21
- [PULL 07/55] tests/tcg: build tests with -Werror, Paolo Bonzini, 2020/12/21
- [PULL 14/55] qom: Assert that objects being destroyed have no parent, Paolo Bonzini, 2020/12/21
- [PULL 16/55] configure,meson: add option to enable LTO, Paolo Bonzini, 2020/12/21
- [PULL 17/55] cfi: Initial support for cfi-icall in QEMU, Paolo Bonzini, 2020/12/21
- [PULL 33/55] configure: remove variable bogus_os, Paolo Bonzini, 2020/12/21
- [PULL 40/55] bzip2: convert to meson, Paolo Bonzini, 2020/12/21
- [PULL 39/55] glusterfs: convert to meson, Paolo Bonzini, 2020/12/21
- [PULL 15/55] target/i386: Check privilege level for protected mode 'int N' task gate,
Paolo Bonzini <=
- [PULL 18/55] check-block: enable iotests with cfi-icall, Paolo Bonzini, 2020/12/21
- [PULL 19/55] configure,meson: support Control-Flow Integrity, Paolo Bonzini, 2020/12/21
- [PULL 20/55] docs: Add CFI Documentation, Paolo Bonzini, 2020/12/21
- [PULL 29/55] meson: use pkg-config method for libudev, Paolo Bonzini, 2020/12/21
- [PULL 25/55] Makefile: add dummy target for build.ninja dependencies, Paolo Bonzini, 2020/12/21
- [PULL 43/55] libssh: convert to meson, Paolo Bonzini, 2020/12/21
- [PULL 48/55] zstd: convert to meson, Paolo Bonzini, 2020/12/21
- [PULL 50/55] virtfs: convert to meson, Paolo Bonzini, 2020/12/21
- [PULL 13/55] test-char: Destroy chardev correctly at char_file_test_internal(), Paolo Bonzini, 2020/12/21
- [PULL 35/55] configure: remove CONFIG_FILEVERSION and CONFIG_PRODUCTVERSION, Paolo Bonzini, 2020/12/21