From mboxrd@z Thu Jan 1 00:00:00 1970 From: Peter Feiner Subject: [kvm-unit-tests v2 3/8] x86: realmode: fix test_sgdt_sidt overflow Date: Wed, 2 Mar 2016 17:09:33 -0800 Message-ID: <1456967378-6367-4-git-send-email-pfeiner@google.com> References: <1456867658-10937-1-git-send-email-pfeiner@google.com> <1456967378-6367-1-git-send-email-pfeiner@google.com> Cc: pfeiner@google.com To: kvm@vger.kernel.org, drjones@redhat.com, pbonzini@redhat.com Return-path: Received: from mail-pa0-f49.google.com ([209.85.220.49]:35470 "EHLO mail-pa0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753077AbcCCBJw (ORCPT ); Wed, 2 Mar 2016 20:09:52 -0500 Received: by mail-pa0-f49.google.com with SMTP id bj10so4195669pad.2 for ; Wed, 02 Mar 2016 17:09:51 -0800 (PST) In-Reply-To: <1456967378-6367-1-git-send-email-pfeiner@google.com> Sender: kvm-owner@vger.kernel.org List-ID: In real mode, both sgdt and sidt write 6 bytes to the given memory address: 2 byte limit, 3 byte address, 1 zero byte. However, the test was only allocating 4 bytes. Given an inopportune stack layout, the output was being overwritten and the assertion failed. I discovered this problem when compiling with -fno-omit-stack-pointer. Signed-off-by: Peter Feiner --- x86/realmode.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/x86/realmode.c b/x86/realmode.c index 09e6aa7..6411654 100644 --- a/x86/realmode.c +++ b/x86/realmode.c @@ -116,16 +116,18 @@ struct regs { u32 eip, eflags; }; +struct table_descr { + u16 limit; + void *base; +} __attribute__((packed)); + static u64 gdt[] = { 0, 0x00cf9b000000ffffull, // flat 32-bit code segment 0x00cf93000000ffffull, // flat 32-bit data segment }; -static struct { - u16 limit; - void *base; -} __attribute__((packed)) gdt_descr = { +static struct table_descr gdt_descr = { sizeof(gdt) - 1, gdt, }; @@ -1417,21 +1419,23 @@ static void test_ss_base_for_esp_ebp(void) report("ss relative addressing (2)", R_AX | R_BX, outregs.ebx == 0x87654321); } +extern unsigned long long r_gdt[]; + static void test_sgdt_sidt(void) { MK_INSN(sgdt, "sgdtw (%eax)"); MK_INSN(sidt, "sidtw (%eax)"); - unsigned x, y; + struct table_descr x, y; inregs.eax = (unsigned)&y; asm volatile("sgdtw %0" : "=m"(x)); exec_in_big_real_mode(&insn_sgdt); - report("sgdt", 0, x == y); + report("sgdt", 0, x.limit == y.limit && x.base == y.base); inregs.eax = (unsigned)&y; asm volatile("sidtw %0" : "=m"(x)); exec_in_big_real_mode(&insn_sidt); - report("sidt", 0, x == y); + report("sidt", 0, x.limit == y.limit && x.base == y.base); } static void test_sahf(void) @@ -1734,10 +1738,7 @@ void realmode_start(void) unsigned long long r_gdt[] = { 0, 0x9b000000ffff, 0x93000000ffff }; -struct __attribute__((packed)) { - unsigned short limit; - void *base; -} r_gdt_descr = { sizeof(r_gdt) - 1, &r_gdt }; +struct table_descr r_gdt_descr = { sizeof(r_gdt) - 1, &r_gdt }; asm( ".section .init \n\t" -- 2.7.0.rc3.207.g0ac5344