Received: by 10.213.65.68 with SMTP id h4csp1743591imn; Mon, 19 Mar 2018 12:03:04 -0700 (PDT) X-Google-Smtp-Source: AG47ELszX5UYZIXhRGzKj7Rw3RnL8QLNWT9webrhtgGkvLJZSXNmmNv84MouaeVEXMPhKzZ4QhVf X-Received: by 2002:a17:902:968a:: with SMTP id n10-v6mr7986836plp.397.1521486184075; Mon, 19 Mar 2018 12:03:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521486184; cv=none; d=google.com; s=arc-20160816; b=Py4hJsC2YBUbr5rPGOPeu7Hnyf4KXPoqRPFojoaT9byiHopCv4BpZGEqY+j0OCIYgf Tkr2DP+yt5ZHD8ziOeyjXPjgSFNJNE8zLNTtRKyrcLteOl7EhhnTtmygoUnaVAUquC23 tN4o5af4QX6Zhu0gnczgwIiMs306h3Qpz+zraeXEn5YdlWmvnqVufBr3Hc0wtNpuECC0 YmpWOpUVKOBv5FHW+hIM2oZLi6Ny+mgGMbKwMHYtdBoPmuKn0+ej8GVXdZsAnI3awqce fYuZErBRHsWDPX9SMUgxo3XP8yCzDh7BvBxj76+rvLuXqR4cwXRweWELzmHGGntzM+UV 5jVQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=xVEwT1rDw53Elxf7JpX/tDNUevArs07WzgRVR4ApLwo=; b=mUAJsllXzyJ0p0WDysdugsSg/7hY5vPwCkZKsZ0eLrB8ljD3jNZG94Vp6pTVxd1MqR pQqTCHJrmiY0JGZ7+T+tCz5246ahHSA0Izk6OXKynkE8tyrYjJvhCgiOUqJuWvf54SSX 0GbJS9YdH467tzjmz3hiAiuiHg3862p8FTqcawF/IwLZiA0LLoJ57oaaDXN++rDJ1Mj5 XLj8DjQ74fShdbpQIa3WTkAUSz4vfrfk3jYH/uvuGbyFbX6a9IEJwOeeG2pfY4sAYwjJ tW2DhTWcba+bxx4kINyr6vixj3rgJL0MRVuEoqjE0C5uoW2gEO8nO9p+8h4ZV6tDT1Kb 4sVg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k6-v6si524396pln.103.2018.03.19.12.02.50; Mon, 19 Mar 2018 12:03:04 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S970672AbeCSS7c (ORCPT + 99 others); Mon, 19 Mar 2018 14:59:32 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:52602 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1031800AbeCSS3J (ORCPT ); Mon, 19 Mar 2018 14:29:09 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 1FECD10A7; Mon, 19 Mar 2018 18:29:07 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Ricardo Neri , Thomas Gleixner , Andrew Morton , Andy Lutomirski , Borislav Petkov , Borislav Petkov , Brian Gerst , Chen Yucong , Chris Metcalf , Dave Hansen , Denys Vlasenko , Fenghua Yu , "H. Peter Anvin" , Huang Rui , Jiri Slaby , Jonathan Corbet , Josh Poimboeuf , Linus Torvalds , Masami Hiramatsu , "Michael S. Tsirkin" , Paolo Bonzini , Paul Gortmaker , Peter Zijlstra , "Ravi V. Shankar" , Shuah Khan , Tony Luck , Vlastimil Babka , ricardo.neri@intel.com, Ingo Molnar Subject: [PATCH 4.9 214/241] selftests/x86: Add tests for User-Mode Instruction Prevention Date: Mon, 19 Mar 2018 19:07:59 +0100 Message-Id: <20180319180800.035896589@linuxfoundation.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180319180751.172155436@linuxfoundation.org> References: <20180319180751.172155436@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.9-stable review patch. If anyone has any objections, please let me know. ------------------ From: Ricardo Neri commit 9390afebe1d3f5a0be18b1afdd0ce09d67cebf9e upstream. Certain user space programs that run on virtual-8086 mode may utilize instructions protected by the User-Mode Instruction Prevention (UMIP) security feature present in new Intel processors: SGDT, SIDT and SMSW. In such a case, a general protection fault is issued if UMIP is enabled. When such a fault happens, the kernel traps it and emulates the results of these instructions with dummy values. The purpose of this new test is to verify whether the impacted instructions can be executed without causing such #GP. If no #GP exceptions occur, we expect to exit virtual-8086 mode from INT3. The instructions protected by UMIP are executed in representative use cases: a) displacement-only memory addressing b) register-indirect memory addressing c) results stored directly in operands Unfortunately, it is not possible to check the results against a set of expected values because no emulation will occur in systems that do not have the UMIP feature. Instead, results are printed for verification. A simple verification is done to ensure that results of all tests are identical. Signed-off-by: Ricardo Neri Reviewed-by: Thomas Gleixner Cc: Andrew Morton Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Borislav Petkov Cc: Brian Gerst Cc: Chen Yucong Cc: Chris Metcalf Cc: Dave Hansen Cc: Denys Vlasenko Cc: Fenghua Yu Cc: H. Peter Anvin Cc: Huang Rui Cc: Jiri Slaby Cc: Jonathan Corbet Cc: Josh Poimboeuf Cc: Linus Torvalds Cc: Masami Hiramatsu Cc: Michael S. Tsirkin Cc: Paolo Bonzini Cc: Paul Gortmaker Cc: Peter Zijlstra Cc: Ravi V. Shankar Cc: Shuah Khan Cc: Tony Luck Cc: Vlastimil Babka Cc: ricardo.neri@intel.com Link: http://lkml.kernel.org/r/1509935277-22138-12-git-send-email-ricardo.neri-calderon@linux.intel.com Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- tools/testing/selftests/x86/entry_from_vm86.c | 73 +++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) --- a/tools/testing/selftests/x86/entry_from_vm86.c +++ b/tools/testing/selftests/x86/entry_from_vm86.c @@ -95,6 +95,22 @@ asm ( "int3\n\t" "vmcode_int80:\n\t" "int $0x80\n\t" + "vmcode_umip:\n\t" + /* addressing via displacements */ + "smsw (2052)\n\t" + "sidt (2054)\n\t" + "sgdt (2060)\n\t" + /* addressing via registers */ + "mov $2066, %bx\n\t" + "smsw (%bx)\n\t" + "mov $2068, %bx\n\t" + "sidt (%bx)\n\t" + "mov $2074, %bx\n\t" + "sgdt (%bx)\n\t" + /* register operands, only for smsw */ + "smsw %ax\n\t" + "mov %ax, (2080)\n\t" + "int3\n\t" ".size vmcode, . - vmcode\n\t" "end_vmcode:\n\t" ".code32\n\t" @@ -103,7 +119,7 @@ asm ( extern unsigned char vmcode[], end_vmcode[]; extern unsigned char vmcode_bound[], vmcode_sysenter[], vmcode_syscall[], - vmcode_sti[], vmcode_int3[], vmcode_int80[]; + vmcode_sti[], vmcode_int3[], vmcode_int80[], vmcode_umip[]; /* Returns false if the test was skipped. */ static bool do_test(struct vm86plus_struct *v86, unsigned long eip, @@ -160,6 +176,58 @@ static bool do_test(struct vm86plus_stru return true; } +void do_umip_tests(struct vm86plus_struct *vm86, unsigned char *test_mem) +{ + struct table_desc { + unsigned short limit; + unsigned long base; + } __attribute__((packed)); + + /* Initialize variables with arbitrary values */ + struct table_desc gdt1 = { .base = 0x3c3c3c3c, .limit = 0x9999 }; + struct table_desc gdt2 = { .base = 0x1a1a1a1a, .limit = 0xaeae }; + struct table_desc idt1 = { .base = 0x7b7b7b7b, .limit = 0xf1f1 }; + struct table_desc idt2 = { .base = 0x89898989, .limit = 0x1313 }; + unsigned short msw1 = 0x1414, msw2 = 0x2525, msw3 = 3737; + + /* UMIP -- exit with INT3 unless kernel emulation did not trap #GP */ + do_test(vm86, vmcode_umip - vmcode, VM86_TRAP, 3, "UMIP tests"); + + /* Results from displacement-only addressing */ + msw1 = *(unsigned short *)(test_mem + 2052); + memcpy(&idt1, test_mem + 2054, sizeof(idt1)); + memcpy(&gdt1, test_mem + 2060, sizeof(gdt1)); + + /* Results from register-indirect addressing */ + msw2 = *(unsigned short *)(test_mem + 2066); + memcpy(&idt2, test_mem + 2068, sizeof(idt2)); + memcpy(&gdt2, test_mem + 2074, sizeof(gdt2)); + + /* Results when using register operands */ + msw3 = *(unsigned short *)(test_mem + 2080); + + printf("[INFO]\tResult from SMSW:[0x%04x]\n", msw1); + printf("[INFO]\tResult from SIDT: limit[0x%04x]base[0x%08lx]\n", + idt1.limit, idt1.base); + printf("[INFO]\tResult from SGDT: limit[0x%04x]base[0x%08lx]\n", + gdt1.limit, gdt1.base); + + if (msw1 != msw2 || msw1 != msw3) + printf("[FAIL]\tAll the results of SMSW should be the same.\n"); + else + printf("[PASS]\tAll the results from SMSW are identical.\n"); + + if (memcmp(&gdt1, &gdt2, sizeof(gdt1))) + printf("[FAIL]\tAll the results of SGDT should be the same.\n"); + else + printf("[PASS]\tAll the results from SGDT are identical.\n"); + + if (memcmp(&idt1, &idt2, sizeof(idt1))) + printf("[FAIL]\tAll the results of SIDT should be the same.\n"); + else + printf("[PASS]\tAll the results from SIDT are identical.\n"); +} + int main(void) { struct vm86plus_struct v86; @@ -218,6 +286,9 @@ int main(void) v86.regs.eax = (unsigned int)-1; do_test(&v86, vmcode_int80 - vmcode, VM86_INTx, 0x80, "int80"); + /* UMIP -- should exit with INTx 0x80 unless UMIP was not disabled */ + do_umip_tests(&v86, addr); + /* Execute a null pointer */ v86.regs.cs = 0; v86.regs.ss = 0;